소스 검색

Added a 3D transform property sheet to entity editor, fixed transform gizmo to always follow selected entities positions, changed Quaternion's toEulerAngles to returning the vector, changed Entity's internal euler rotation storage to Vector3

Ivan Safrin 12 년 전
부모
커밋
fc92ccdb5d

+ 13 - 1
Core/Contents/Include/PolyEntity.h

@@ -352,6 +352,12 @@ namespace Polycode {
 			@return Entity's scale as a vector.
 			@return Entity's scale as a vector.
 			*/						
 			*/						
 			Vector3 getScale() const;
 			Vector3 getScale() const;
+        
+            /**
+             * Returns the entity's rotation as euler angles
+             @return Entity's rotation as euler angles
+             */
+            Vector3 getEulerRotation() const;
 		
 		
 			/**
 			/**
 			* Returns the entity's pitch combined with the combined pitch of its parent.
 			* Returns the entity's pitch combined with the combined pitch of its parent.
@@ -376,6 +382,12 @@ namespace Polycode {
 			*/
 			*/
 			void rebuildRotation();					
 			void rebuildRotation();					
 			
 			
+            /**
+             * Sets rotation from euler angles
+             * @param rotation New rotation values
+             */
+            void setRotationEuler(const Vector3 &rotation);
+        
 			/**
 			/**
 			* Sets the pitch rotation of the entity.
 			* Sets the pitch rotation of the entity.
 			* @param pitch New pitch value in degrees.
 			* @param pitch New pitch value in degrees.
@@ -734,7 +746,7 @@ namespace Polycode {
 		
 		
 			Vector3 position;
 			Vector3 position;
 			Vector3 scale;		
 			Vector3 scale;		
-			Rotation rotation;
+			Vector3 rotation;
 	
 	
 			Quaternion rotationQuat;
 			Quaternion rotationQuat;
 			
 			

+ 2 - 6
Core/Contents/Include/PolyQuaternion.h

@@ -239,12 +239,8 @@ namespace Polycode {
 				z = fSin*rkAxis.z;
 				z = fSin*rkAxis.z;
 			}
 			}
 
 
-			void toEulerAngles (Vector3& eulerAngles) {
-				// See http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
-				// q0 = w, q1 = x, q2 = y, q3 = z
-				eulerAngles.x = atan2( 2 * ( w * x + y * z), 1 - 2 * (x * x + y * y) );
-				eulerAngles.y = asin(2 * ( w * y - z * x));
-				eulerAngles.z = atan2( 2 * ( w * z + x * y), 1 - 2 * (y * y + z * z) );
+			Vector3 toEulerAngles () const {
+                return Vector3(atan2( 2 * ( w * x + y * z), 1 - 2 * (x * x + y * y)), asin(2 * ( w * y - z * x)), atan2( 2 * ( w * z + x * y), 1 - 2 * (y * y + z * z) ));
 			}
 			}
 
 
 			//-----------------------------------------------------------------------
 			//-----------------------------------------------------------------------

+ 28 - 17
Core/Contents/Source/PolyEntity.cpp

@@ -443,7 +443,7 @@ Vector3 Entity::getCompoundScale() const {
 
 
 Matrix4 Entity::getConcatenatedRollMatrix() const {
 Matrix4 Entity::getConcatenatedRollMatrix() const {
 	Quaternion q;
 	Quaternion q;
-	q.createFromAxisAngle(0.0f, 0.0f, 1.0f, rotation.roll);
+	q.createFromAxisAngle(0.0f, 0.0f, 1.0f, rotation.z);
 	Matrix4 transformMatrix = q.createMatrix();	
 	Matrix4 transformMatrix = q.createMatrix();	
 	
 	
 	if(parentEntity != NULL) 
 	if(parentEntity != NULL) 
@@ -591,11 +591,13 @@ void Entity::setRotationQuat(Number w, Number x, Number y, Number z) {
 	rotationQuat.x = x;
 	rotationQuat.x = x;
 	rotationQuat.y = y;
 	rotationQuat.y = y;
 	rotationQuat.z = z;
 	rotationQuat.z = z;
+    rotation = rotationQuat.toEulerAngles();
 	matrixDirty = true;
 	matrixDirty = true;
 }
 }
 
 
 void Entity::setRotationByQuaternion(const Quaternion &quaternion) {
 void Entity::setRotationByQuaternion(const Quaternion &quaternion) {
 	rotationQuat = quaternion;
 	rotationQuat = quaternion;
+    rotation = quaternion.toEulerAngles();
 	matrixDirty = true;
 	matrixDirty = true;
 }
 }
 
 
@@ -607,6 +609,10 @@ Vector3 Entity::getScale() const {
 	return scale;
 	return scale;
 }
 }
 
 
+Vector3 Entity::getEulerRotation() const {
+    return rotation;
+}
+
 Matrix4 Entity::getConcatenatedMatrixRelativeTo(Entity *relativeEntity) {
 Matrix4 Entity::getConcatenatedMatrixRelativeTo(Entity *relativeEntity) {
 	
 	
 	if(matrixDirty)
 	if(matrixDirty)
@@ -641,44 +647,49 @@ const Matrix4& Entity::getTransformMatrix() const {
 }
 }
 
 
 void Entity::Pitch(Number pitch) {
 void Entity::Pitch(Number pitch) {
-	rotation.pitch += pitch;
+	rotation.x += pitch;
 	rebuildRotation();	
 	rebuildRotation();	
 	matrixDirty = true;
 	matrixDirty = true;
 }
 }
 
 
 void Entity::Yaw(Number yaw) {
 void Entity::Yaw(Number yaw) {
-	rotation.yaw += yaw;
+	rotation.y += yaw;
 	rebuildRotation();	
 	rebuildRotation();	
 	matrixDirty = true;
 	matrixDirty = true;
 }
 }
 
 
 void Entity::Roll(Number roll) {
 void Entity::Roll(Number roll) {
-	rotation.roll += roll;
+	rotation.z += roll;
 	rebuildRotation();	
 	rebuildRotation();	
 	matrixDirty = true;
 	matrixDirty = true;
 }
 }
 
 
 void Entity::setRoll(Number roll) {
 void Entity::setRoll(Number roll) {
-	rotation.roll = roll;
+	rotation.z = roll;
 	rebuildRotation();	
 	rebuildRotation();	
 	matrixDirty = true;
 	matrixDirty = true;
 }
 }
 
 
 void Entity::setPitch(Number pitch) {
 void Entity::setPitch(Number pitch) {
-	rotation.pitch = pitch;
+	rotation.x = pitch;
 	rebuildRotation();	
 	rebuildRotation();	
 	matrixDirty = true;
 	matrixDirty = true;
 }
 }
 
 
 void Entity::setYaw(Number yaw) {
 void Entity::setYaw(Number yaw) {
-	rotation.yaw = yaw;
+	rotation.y = yaw;
 	rebuildRotation();
 	rebuildRotation();
 	matrixDirty = true;
 	matrixDirty = true;
 }
 }
 
 
+void Entity::setRotationEuler(const Vector3 &rotation) {
+    this->rotation = rotation;
+    rebuildRotation();
+    matrixDirty = true;
+}
 
 
 void Entity::rebuildRotation() {
 void Entity::rebuildRotation() {
-	rotationQuat.fromAxes(rotation.pitch, rotation.yaw, rotation.roll);
+	rotationQuat.fromAxes(rotation.x, rotation.y, rotation.z);
 }
 }
 
 
 void Entity::setEntityProp(const String& propName, const String& propValue) {
 void Entity::setEntityProp(const String& propName, const String& propValue) {
@@ -742,15 +753,15 @@ Number Entity::getDepth() const {
 
 
 
 
 Number Entity::getPitch() const {
 Number Entity::getPitch() const {
-	return rotation.pitch;
+	return rotation.x;
 }
 }
 
 
 Number Entity::getYaw() const {
 Number Entity::getYaw() const {
-	return rotation.yaw;
+	return rotation.y;
 }
 }
 
 
 Number Entity::getRoll() const {
 Number Entity::getRoll() const {
-	return rotation.roll;
+	return rotation.z;
 }
 }
 
 
 void Entity::setTransformByMatrixPure(const Matrix4& matrix) {
 void Entity::setTransformByMatrixPure(const Matrix4& matrix) {
@@ -847,23 +858,23 @@ Vector2 Entity::getPosition2D() const {
 
 
 Number Entity::getCombinedPitch() const {
 Number Entity::getCombinedPitch() const {
 	if(parentEntity != NULL)
 	if(parentEntity != NULL)
-		return parentEntity->getCombinedPitch()+rotation.pitch;
+		return parentEntity->getCombinedPitch()+rotation.x;
 	else
 	else
-		return rotation.pitch;
+		return rotation.x;
 }
 }
 
 
 Number Entity::getCombinedYaw() const {
 Number Entity::getCombinedYaw() const {
 	if(parentEntity != NULL)
 	if(parentEntity != NULL)
-		return parentEntity->getCombinedYaw()+rotation.yaw;
+		return parentEntity->getCombinedYaw()+rotation.y;
 	else
 	else
-		return rotation.yaw;
+		return rotation.y;
 }
 }
 
 
 Number Entity::getCombinedRoll() const {
 Number Entity::getCombinedRoll() const {
 	if(parentEntity != NULL)
 	if(parentEntity != NULL)
-		return parentEntity->getCombinedRoll()+rotation.roll;
+		return parentEntity->getCombinedRoll()+rotation.z;
 	else
 	else
-		return rotation.roll;	
+		return rotation.z;
 }
 }
 
 
 unsigned int Entity::getNumTags() const {
 unsigned int Entity::getNumTags() const {

+ 2 - 0
IDE/Contents/Include/EntityEditorPropertyView.h

@@ -42,6 +42,8 @@ class EntityEditorPropertyView : public UIElement {
     protected:
     protected:
     
     
         PropList *entityProps;
         PropList *entityProps;
+    
+        TransformSheet *transformSheet;    
         EntitySheet *entitySheet;
         EntitySheet *entitySheet;
         MaterialPropSheet *materialSheet;
         MaterialPropSheet *materialSheet;
         ScenePrimitiveSheet *primitiveSheet;
         ScenePrimitiveSheet *primitiveSheet;

+ 36 - 2
IDE/Contents/Include/PolycodeProps.h

@@ -52,6 +52,28 @@ class PropProp : public UIElement {
 		bool settingFromData;
 		bool settingFromData;
 };
 };
 
 
+class Vector3Prop : public PropProp {
+public:
+    Vector3Prop(String caption);
+    ~Vector3Prop();
+    void handleEvent(Event *event);
+    void set(const Vector3 &position);
+
+    Vector3 get() const;
+    void setPropData(PolycodeEditorPropActionData* data);
+    
+    void setPropWidth(Number width);
+    
+    UITextInput *xInput;
+    UITextInput *yInput;
+    UITextInput *zInput;
+    
+    UILabel *labelX;
+    UILabel *labelY;
+    UILabel *labelZ;
+};
+
+
 class Vector2Prop : public PropProp {
 class Vector2Prop : public PropProp {
 	public:
 	public:
 		Vector2Prop(String caption);
 		Vector2Prop(String caption);
@@ -509,17 +531,29 @@ class RenderTargetsSheet : public PropSheet {
 		UIButton *addButton;		
 		UIButton *addButton;		
 		int removeIndex;
 		int removeIndex;
 };
 };
-/*
+
 class TransformSheet : public PropSheet {
 class TransformSheet : public PropSheet {
     public:
     public:
         TransformSheet();
         TransformSheet();
         ~TransformSheet();
         ~TransformSheet();
     
     
+        void Update();
+    
         void setEntity(Entity *entity);
         void setEntity(Entity *entity);
+        void handleEvent(Event *event);
+    
     protected:
     protected:
         Entity *entity;
         Entity *entity;
+    
+        Vector3Prop *positionProp;
+        Vector3Prop *scaleProp;
+        Vector3Prop *rotationProp;
+    
+        Vector3 lastPosition;
+        Vector3 lastScale;
+        Vector3 lastRotation;
 };
 };
-*/
+
 class ScenePrimitiveSheet : public PropSheet {
 class ScenePrimitiveSheet : public PropSheet {
 public:
 public:
     ScenePrimitiveSheet();
     ScenePrimitiveSheet();

+ 5 - 0
IDE/Contents/Source/EntityEditorPropertyView.cpp

@@ -27,6 +27,10 @@ EntityEditorPropertyView::EntityEditorPropertyView() : UIElement() {
     entityProps = new PropList();
     entityProps = new PropList();
     addChild(entityProps);
     addChild(entityProps);
     
     
+    transformSheet = new TransformSheet();
+    entityProps->addPropSheet(transformSheet);
+    transformSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
+    
     materialSheet = new MaterialPropSheet();
     materialSheet = new MaterialPropSheet();
     entityProps->addPropSheet(materialSheet);
     entityProps->addPropSheet(materialSheet);
     materialSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
     materialSheet->addEventListener(this, PropEvent::EVENT_PROP_CHANGE);
@@ -55,6 +59,7 @@ void EntityEditorPropertyView::setEntity(Entity *entity) {
     primitiveSheet->setScenePrimitive(scenePrimitive);
     primitiveSheet->setScenePrimitive(scenePrimitive);
 
 
     entitySheet->setEntity(entity);
     entitySheet->setEntity(entity);
+    transformSheet->setEntity(entity);
     Resize(getWidth(), getHeight());
     Resize(getWidth(), getHeight());
 }
 }
 
 

+ 155 - 0
IDE/Contents/Source/PolycodeProps.cpp

@@ -341,6 +341,93 @@ PropProp::~PropProp() {
 
 
 }
 }
 
 
+Vector3Prop::Vector3Prop(String caption) : PropProp(caption, "Vector3") {
+    
+	labelX = new UILabel("X:", 11);
+	labelX->color.a = 1.0;
+	propContents->addChild(labelX);
+	labelX->setPosition(-20, 6);
+    
+	labelY = new UILabel("Y:", 11);
+	labelY->color.a = 1.0;
+	propContents->addChild(labelY);
+	labelY->setPosition(-20, 31);
+
+    labelZ = new UILabel("Z:", 11);
+	labelZ->color.a = 1.0;
+	propContents->addChild(labelZ);
+	labelZ->setPosition(-20, 56);
+    
+	xInput = new UITextInput(false, 50, 12);
+	xInput->addEventListener(this, UIEvent::CHANGE_EVENT);
+	xInput->setText("0");
+	xInput->setNumberOnly(true);
+	propContents->addChild(xInput);
+	xInput->setPosition(0, 0);
+
+   	yInput = new UITextInput(false, 50, 12);
+	yInput->addEventListener(this, UIEvent::CHANGE_EVENT);
+	yInput->setText("0");
+	yInput->setNumberOnly(true);
+	propContents->addChild(yInput);
+	yInput->setPosition(0, 25);
+
+    zInput = new UITextInput(false, 50, 12);
+	zInput->addEventListener(this, UIEvent::CHANGE_EVENT);
+	zInput->setText("0");
+	zInput->setNumberOnly(true);
+	propContents->addChild(zInput);
+	zInput->setPosition(0, 50);
+
+	setHeight(75);
+}
+
+void Vector3Prop::setPropWidth(Number width) {
+    xInput->Resize(width-PROP_PADDING-propContents->getPosition().x, xInput->getHeight());
+    yInput->Resize(width-PROP_PADDING-propContents->getPosition().x, yInput->getHeight());
+    zInput->Resize(width-PROP_PADDING-propContents->getPosition().x, zInput->getHeight());
+}
+
+void Vector3Prop::handleEvent(Event *event) {
+
+	if(event->getDispatcher() == xInput || event->getDispatcher() == yInput || event->getDispatcher() == zInput) {
+		if(event->getEventCode() == UIEvent::CHANGE_EVENT) {
+            
+//			if(xInput && yInput && zInput) {
+//				lastData = currentData;
+//				currentData = Vector2(atof(positionX->getText().c_str()), atof(positionY->getText().c_str()));
+//			}
+			if(!suppressChangeEvent) {
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+//				dispatchEvent(new PropEvent(this, NULL, PropDataVector2(lastData), PropDataVector2(currentData)), PropEvent::EVENT_PROP_CHANGE);
+                
+			}
+		}
+	}
+
+}
+
+void Vector3Prop::setPropData(PolycodeEditorPropActionData* data) {
+//	set(data->vector2Val);
+	dispatchEvent(new Event(), Event::CHANGE_EVENT);
+}
+
+void Vector3Prop::set(const Vector3 &position) {
+	suppressChangeEvent = true;
+	xInput->setText(String::NumberToString(position.x, 5));
+	yInput->setText(String::NumberToString(position.y, 5));
+	zInput->setText(String::NumberToString(position.z, 5));
+	suppressChangeEvent = false;
+}
+
+Vector3 Vector3Prop::get() const {
+	return Vector3(atof(xInput->getText().c_str()), atof(yInput->getText().c_str()), atof(zInput->getText().c_str()));
+}
+
+Vector3Prop::~Vector3Prop() {
+    
+}
+
 Vector2Prop::Vector2Prop(String caption) : PropProp(caption, "Vector2") {
 Vector2Prop::Vector2Prop(String caption) : PropProp(caption, "Vector2") {
 
 
 	labelX = new UILabel("X:", 11);
 	labelX = new UILabel("X:", 11);
@@ -2041,6 +2128,74 @@ void ShaderTexturesSheet::setShader(Shader *shader, Material *material, ShaderBi
 	Resize(getWidth(), getHeight());
 	Resize(getWidth(), getHeight());
 }
 }
 
 
+TransformSheet::TransformSheet() : PropSheet("TRANSFORM", "entity_transform") {
+    entity = NULL;
+    
+    positionProp = new Vector3Prop("Position");
+    addProp(positionProp);
+    
+    scaleProp = new Vector3Prop("Scale");
+    addProp(scaleProp);
+    
+    rotationProp = new Vector3Prop("Rotation");
+    addProp(rotationProp);
+    
+    propHeight = 275;
+    
+    enabled = false;
+}
+
+TransformSheet::~TransformSheet() {
+
+}
+
+
+void TransformSheet::setEntity(Entity *entity) {
+    this->entity = entity;
+    if(entity) {
+        enabled = true;
+    } else {
+        enabled = false;
+    }
+}
+
+void TransformSheet::Update() {
+    if(!entity) {
+        return;
+    }
+    
+    if(entity->getPosition() != lastPosition) {
+        positionProp->set(entity->getPosition());
+        lastPosition = entity->getPosition();
+    }
+    
+    if(entity->getScale() != lastScale) {
+        scaleProp->set(entity->getScale());
+        lastScale = entity->getScale();
+    }
+    
+    if(entity->getEulerRotation() != lastRotation) {
+        rotationProp->set(entity->getEulerRotation() * TODEGREES);
+        lastRotation = entity->getEulerRotation() * TODEGREES;
+    }
+}
+
+void TransformSheet::handleEvent(Event *event) {
+    if(event->getEventCode() == Event::CHANGE_EVENT) {
+        if(event->getDispatcher() == positionProp) {
+            lastPosition = positionProp->get();
+            entity->setPosition(lastPosition);
+        } else if(event->getDispatcher() == scaleProp) {
+            lastScale = scaleProp->get();
+            entity->setScale(lastScale);
+        } else if(event->getDispatcher() == rotationProp) {
+            lastRotation = rotationProp->get();
+            entity->setRotationEuler(lastRotation);
+        }
+    }
+    PropSheet::handleEvent(event);
+}
+
 ScenePrimitiveSheet::ScenePrimitiveSheet() : PropSheet("PRIMITIVE", "scene_primitive") {
 ScenePrimitiveSheet::ScenePrimitiveSheet() : PropSheet("PRIMITIVE", "scene_primitive") {
     typeProp = new ComboProp("Type");
     typeProp = new ComboProp("Type");
     typeProp->comboEntry->addComboItem("Box");
     typeProp->comboEntry->addComboItem("Box");

+ 10 - 1
IDE/Contents/Source/TransformGizmo.cpp

@@ -416,7 +416,6 @@ void TransformGizmo::transfromSelectedEntities(const Vector3 &move, const Vector
 		q.fromAngleAxis(rotate, axisVector);
 		q.fromAngleAxis(rotate, axisVector);
 		selectedEntities[i]->setRotationByQuaternion(currentRotation * q);
 		selectedEntities[i]->setRotationByQuaternion(currentRotation * q);
 	}
 	}
-	Translate(move);
 }
 }
 
 
 Number TransformGizmo::getTransformPlaneAngle() {
 Number TransformGizmo::getTransformPlaneAngle() {
@@ -583,6 +582,16 @@ TransformGizmo::~TransformGizmo() {
 }
 }
 
 
 void TransformGizmo::Update() {
 void TransformGizmo::Update() {
+    
+    if(selectedEntities.size() > 0) {
+        Vector3 centerPoint;
+        for(int i=0; i < selectedEntities.size(); i++) {
+            centerPoint += selectedEntities[i]->getConcatenatedMatrix().getPosition();
+        }
+        centerPoint = centerPoint / selectedEntities.size();
+        setPosition(centerPoint);
+    }
+    
     viewportRotateGripBase->lookAt(targetCamera->getPosition());
     viewportRotateGripBase->lookAt(targetCamera->getPosition());
 	Number scale = getPosition().distance(targetCamera->getPosition()) * 0.1;
 	Number scale = getPosition().distance(targetCamera->getPosition()) * 0.1;
     if(scale < 0.0) {
     if(scale < 0.0) {