Index: code/branches/presentation/src/orxonox/collisionshapes/CompoundCollisionShape.cc
===================================================================
--- code/branches/presentation/src/orxonox/collisionshapes/CompoundCollisionShape.cc	(revision 8499)
+++ code/branches/presentation/src/orxonox/collisionshapes/CompoundCollisionShape.cc	(revision 8556)
@@ -27,4 +27,9 @@
  */
 
+/**
+    @file CompoundCollisionShape.cc
+    @brief Implementation of the CompoundCollisionShape class.
+*/
+
 #include "CompoundCollisionShape.h"
 
@@ -39,4 +44,8 @@
     CreateFactory(CompoundCollisionShape);
 
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
     CompoundCollisionShape::CompoundCollisionShape(BaseObject* creator) : CollisionShape(creator)
     {
@@ -46,4 +55,9 @@
     }
 
+    /**
+    @brief
+        Destructor.
+        Deletes all its children.
+    */
     CompoundCollisionShape::~CompoundCollisionShape()
     {
@@ -70,8 +84,16 @@
     }
 
+    /**
+    @brief
+        Attach the input CollisionShape to the CompoundCollisionShape.
+    @param shape
+        A pointer to the CollisionShape that is to be attached.
+    */
     void CompoundCollisionShape::attach(CollisionShape* shape)
     {
+        // If either the input shape is NULL or we try to attach the CollisionShape to itself.
         if (!shape || static_cast<CollisionShape*>(this) == shape)
             return;
+
         if (this->attachedShapes_.find(shape) != this->attachedShapes_.end())
         {
@@ -80,13 +102,16 @@
         }
 
+        // Notify the CollisionShape that it is being attached to the CompoundCollisionShape.
         if (!shape->notifyBeingAttached(this))
             return;
 
+        // Attach it.
         this->attachedShapes_[shape] = shape->getCollisionShape();
 
+        // Only actually attach if we didn't pick a CompoundCollisionShape with no content.
         if (shape->getCollisionShape())
         {
-            // Only actually attach if we didn't pick a CompoundCollisionShape with no content
             btTransform transf(multi_cast<btQuaternion>(shape->getOrientation()), multi_cast<btVector3>(shape->getPosition()));
+            // Add the btCollisionShape of the CollisionShape as a child shape to the btCompoundShape of the CompoundCollisionShape.
             this->compoundShape_->addChildShape(transf, shape->getCollisionShape());
 
@@ -95,11 +120,18 @@
     }
 
+    /**
+    @brief
+        Detach the input CollisionShape form the CompoundCollisionShape.
+    @param shape
+        A pointer to the CollisionShape to be detached.
+    */
     void CompoundCollisionShape::detach(CollisionShape* shape)
     {
+        // If the input CollisionShape is actually attached.
         if (this->attachedShapes_.find(shape) != this->attachedShapes_.end())
         {
             this->attachedShapes_.erase(shape);
             if (shape->getCollisionShape())
-                this->compoundShape_->removeChildShape(shape->getCollisionShape());
+                this->compoundShape_->removeChildShape(shape->getCollisionShape()); // TODO: Apparently this is broken?
             shape->notifyDetached();
 
@@ -110,4 +142,8 @@
     }
 
+    /**
+    @brief
+        Detach all attached CollisionShapes.
+    */
     void CompoundCollisionShape::detachAll()
     {
@@ -116,9 +152,18 @@
     }
 
+    /**
+    @brief
+        Update the input CollisionShape that is attached to the CompoundCollisionShape.
+        This is called when the input shape's internal collision shape (a btCollisionShape) has changed.
+    @param shape
+        A pointer to the CollisionShape to be updated.
+    */
     void CompoundCollisionShape::updateAttachedShape(CollisionShape* shape)
     {
         if (!shape)
             return;
+
         std::map<CollisionShape*, btCollisionShape*>::iterator it = this->attachedShapes_.find(shape);
+        // Check whether the input shape belongs to this CompoundCollisionShape.
         if (it == this->attachedShapes_.end())
         {
@@ -129,8 +174,9 @@
         // Remove old btCollisionShape, stored in the children map
         if (it->second)
-            this->compoundShape_->removeChildShape(it->second);
+            this->compoundShape_->removeChildShape(it->second); // TODO: Apparently this is broken?
+
+        // Only actually attach if we didn't pick a CompoundCollisionShape with no content
         if (shape->getCollisionShape())
         {
-            // Only actually attach if we didn't pick a CompoundCollisionShape with no content
             btTransform transf(multi_cast<btQuaternion>(shape->getOrientation()), multi_cast<btVector3>(shape->getPosition()));
             this->compoundShape_->addChildShape(transf, shape->getCollisionShape());
@@ -141,42 +187,57 @@
     }
 
+    /**
+    @brief
+        Updates the public shape, the collision shape this CompoundCollisionShape has to the outside.
+    */
     void CompoundCollisionShape::updatePublicShape()
     {
-        btCollisionShape* primitive = 0;
-        bool bPrimitive = true;
-        bool bEmpty = true;
+        btCollisionShape* primitive = 0; // The primitive shape, if there is one.
+        bool bPrimitive = true; // Whether the CompoundCollisionShape has just one non-empty CollisionShape. And that shape also has no transformation.
+        bool bEmpty = true; // Whether the CompoundCollisionShape is empty.
+        // Iterate over all CollisionShapes that belong to this CompoundCollisionShape.
         for (std::map<CollisionShape*, btCollisionShape*>::const_iterator it = this->attachedShapes_.begin(); it != this->attachedShapes_.end(); ++it)
         {
+            // TODO: Make sure this is correct.
             if (it->second)
             {
                 bEmpty = false;
-                if (!it->first->hasTransform() && !bPrimitive)
+                if (!it->first->hasTransform() && bPrimitive)
                     primitive = it->second;
                 else
+                {
                     bPrimitive = false;
+                    break;
+                }
             }
         }
+
+        // If there is no non-empty CollisionShape.
         if (bEmpty)
         {
+            // If there was none all along, nothing needs to be changed.
             if (this->collisionShape_ == 0)
-            {
-                this->collisionShape_ = 0;
                 return;
-            }
             this->collisionShape_ = 0;
         }
+        // If the CompoundCollisionShape is just a primitive.
+        // Only one shape to be added, no transform; return it directly.
         else if (bPrimitive)
-        {
-            // --> Only one shape to be added, no transform; return it directly
             this->collisionShape_ = primitive;
-        }
+        // Make sure we use the compound shape when returning a btCollisionShape.
         else
-        {
-            // Make sure we use the compound shape when returning a btCollisionShape
             this->collisionShape_ = this->compoundShape_;
-        }
+
         this->updateParent();
     }
 
+    /**
+    @brief
+        Get the attached CollisionShape at the given index.
+    @param index
+        The index of the desired CollisionShape.
+    @return
+        Returns a pointer to the attached CollisionShape at the given index.
+    */
     CollisionShape* CompoundCollisionShape::getAttachedShape(unsigned int index) const
     {
@@ -190,3 +251,49 @@
         return 0;
     }
+
+    /**
+    @brief
+        Is called when the scale of the CompoundCollisionShape has changed.
+        Iterates over all attached CollisionShapes and scales them, then recomputes their compound shape.
+    */
+    void CompoundCollisionShape::changedScale()
+    {
+        CollisionShape::changedScale();
+
+        std::vector<CollisionShape*> shapes;
+        // Iterate through all attached CollisionShapes and add them to the list of shapes.
+        for(std::map<CollisionShape*, btCollisionShape*>::iterator it = this->attachedShapes_.begin(); it != this->attachedShapes_.end(); it++)
+            shapes.push_back(it->first);
+
+        // Delete the compound shape and create a new one.
+        delete this->compoundShape_;
+        this->compoundShape_ = new btCompoundShape();
+
+        // Re-attach all CollisionShapes.
+        for(std::vector<CollisionShape*>::iterator it = shapes.begin(); it != shapes.end(); it++)
+        {
+            CollisionShape* shape = *it;
+            shape->setScale3D(this->getScale3D());
+            // Only actually attach if we didn't pick a CompoundCollisionShape with no content.
+            if (shape->getCollisionShape())
+            {
+                btTransform transf(multi_cast<btQuaternion>(shape->getOrientation()), multi_cast<btVector3>(shape->getPosition()));
+                // Add the btCollisionShape of the CollisionShape as a child shape to the btCompoundShape of the CompoundCollisionShape.
+                this->compoundShape_->addChildShape(transf, shape->getCollisionShape());
+            }
+        }
+
+        this->updatePublicShape();
+
+        /*
+        // Iterate through all attached CollisionShapes
+        for(std::map<CollisionShape*, btCollisionShape*>::const_iterator it = this->attachedShapes_.begin(); it != this->attachedShapes_.end(); it++)
+        {
+            // Rescale the CollisionShape.
+            it->first->setScale3D(this->getScale3D());
+            this->updateAttachedShape(it->first);
+        }
+
+        this->updatePublicShape();*/
+    }
 }
