Index: /trunk/VUT/GtpVisibilityPreprocessor/src/MutualVisibility.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/MutualVisibility.h	(revision 209)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/MutualVisibility.h	(revision 223)
@@ -13,4 +13,12 @@
 };
 
+struct RaySample {
+  /// true if the sample really intersects both boxes
+  float mMinT;
+  float mMaxT;
+  /// intersections of the sample with the scene
+  vector<Ray::Intersection> mIntersections;
+  bool IsValid() const { return mMaxT > 0.0; }
+};
 
 struct RayShaft {
@@ -25,6 +33,5 @@
   Rectangle3 mTarget;
   
-  /// intersections with the scene
-  vector<Ray::Intersection> mIntersections[4];
+  RaySample mSamples[4];
   
   void ComputeError();
@@ -112,7 +119,10 @@
 		  );
 
+  int
+  CastRays(RayShaft &shaft);
+
   void
   ComputeError(RayShaft &sample);
-
+  
   void
   ExportSamples(vector<RayShaft *> &samples);
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Rectangle3.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Rectangle3.h	(revision 221)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Rectangle3.h	(revision 223)
@@ -38,8 +38,5 @@
 	Rectangle3 &r1,
 	Rectangle3 &r2
-	) const
-
-  {//TODO
-  }
+	) const;
   
 };
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/MutualVisibility.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/MutualVisibility.cpp	(revision 209)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/MutualVisibility.cpp	(revision 223)
@@ -27,5 +27,5 @@
   Vector3 origin, direction;
   GetRay(rayIndex, origin, direction);
-  return origin + direction*mIntersections[rayIndex][depth].mT;
+  return origin + direction*mSamples[rayIndex].mIntersections[depth].mT;
 }
 
@@ -76,17 +76,17 @@
   switch (axis) {
   case 0:
-    sample1.mIntersections[0] = sample.mIntersections[0];
-    sample1.mIntersections[3] = sample.mIntersections[3];
-    
-    sample2.mIntersections[1] = sample.mIntersections[1];
-    sample2.mIntersections[2] = sample.mIntersections[2];
+    sample1.mSamples[0].mIntersections = sample.mSamples[0].mIntersections;
+    sample1.mSamples[3].mIntersections = sample.mSamples[3].mIntersections;
+    
+    sample2.mSamples[1].mIntersections = sample.mSamples[1].mIntersections;
+    sample2.mSamples[2].mIntersections = sample.mSamples[2].mIntersections;
     break;
 
   case 1:
-    sample1.mIntersections[0] = sample.mIntersections[0];
-    sample1.mIntersections[1] = sample.mIntersections[1];
-
-    sample2.mIntersections[2] = sample.mIntersections[2];
-    sample2.mIntersections[2] = sample.mIntersections[3];
+    sample1.mSamples[0].mIntersections = sample.mSamples[0].mIntersections;
+    sample1.mSamples[1].mIntersections = sample.mSamples[1].mIntersections;
+
+    sample2.mSamples[2].mIntersections = sample.mSamples[2].mIntersections;
+    sample2.mSamples[3].mIntersections = sample.mSamples[3].mIntersections;
     break;
   }
@@ -148,6 +148,8 @@
 						 )
 {
-  Vector3 normal = target.Center() - source.Center();
-
+  Vector3 sourceCenter = source.Center();
+  Vector3 targetCenter = target.Center();
+  Vector3 normal = Normalize(sourceCenter - targetCenter );
+  
   Plane3 sourcePlane(normal, source.GetVertex(0));
   int i;
@@ -158,9 +160,9 @@
   }
   
-  Plane3 targetPlane(-normal, target.GetVertex(0));
+  Plane3 targetPlane(normal, target.GetVertex(0));
   for (i=1; i < 8; i++) {
     Vector3 v = target.GetVertex(i);
-    if (targetPlane.Distance(v) > 0)
-      targetPlane = Plane3(-normal, v);
+    if (targetPlane.Distance(v) < 0)
+      targetPlane = Plane3(normal, v);
   }
 
@@ -175,13 +177,46 @@
 
   Vector3 yBasis = Normalize( CrossProd(normal, xBasis) );
-  
-  Plane3 bottomPlane(xBasis, source.Center());
-  Plane3 sidePlane(yBasis, source.Center());
-  
-  // cast rays between corresponding vertices of the boxes
-  for (i=0; i < 8; i++) {
-    
-    
-  }
+  // cast rays between the centers of the boxes
+  Vector3 targetRCenter = targetPlane.FindIntersection(sourceCenter,
+						       targetCenter);
+  
+  Vector3 sourceRCenter = sourcePlane.FindIntersection(sourceCenter,
+						       targetCenter);
+  
+
+  Rectangle3 sourceRect;
+  Rectangle3 targetRect;
+
+  
+  float scale = Magnitude(source.Size())*0.7f;
+  sourceRect.mVertices[0] = sourceRCenter - scale*xBasis - scale*yBasis;
+  sourceRect.mVertices[1] = sourceRCenter + scale*xBasis - scale*yBasis;
+  sourceRect.mVertices[2] = sourceRCenter + scale*xBasis + scale*yBasis;
+  sourceRect.mVertices[3] = sourceRCenter - scale*xBasis + scale*yBasis;
+
+  scale = Magnitude(target.Size())*0.7f;
+  targetRect.mVertices[0] = targetRCenter - scale*xBasis - scale*yBasis;
+  targetRect.mVertices[1] = targetRCenter + scale*xBasis - scale*yBasis;
+  targetRect.mVertices[2] = targetRCenter + scale*xBasis + scale*yBasis;
+  targetRect.mVertices[3] = targetRCenter - scale*xBasis + scale*yBasis;
+
+  AddInitialSamples(sourceRect, targetRect, samples);
+
+  //    Plane3 bottomPlane(xBasis, source.Center());
+  //    Plane3 sidePlane(yBasis, source.Center());
+  
+  //    // cast rays between corresponding vertices of the boxes
+  //    for (i=0; i < 8; i++) {
+  //      Vector3 v;
+  //      bool coplanar;
+  //      v = sourcePlane.FindIntersection(source.GetVertex(i),
+  //  				     target.GetVertex(i),
+  //  				     NULL,
+  //  				     &coplanar);
+  //      if (!coplanar) {
+  //        // evaluate source and 
+  
+  //      }
+  //    }
   
   //  AddInitialSamples(sourceRectangle, targetRectangle, samples);
@@ -213,4 +248,9 @@
     sprintf(filename, "samples%04d-%02d.x3d", id++, i);
     Exporter *exporter = Exporter::GetExporter(filename);
+
+    exporter->SetWireframe();
+    exporter->ExportBox(mSource);
+    exporter->ExportBox(mTarget);
+
     exporter->SetFilled();
 
@@ -238,41 +278,69 @@
 
 int
+MutualVisibilitySampler::CastRays(RayShaft &shaft)
+{
+  Ray ray;
+  int i;
+
+  for (i=0; i < 4; i++) {
+    Vector3 origin, direction;
+    shaft.GetRay(i, origin, direction);
+    // determine intersections with the boxes
+    ray.Init(origin, direction, Ray::LINE_SEGMENT);
+    float stmin, stmax, ttmin, ttmax;
+    if ( mSource.GetMinMaxT(ray, &stmin, &stmax) && mTarget.GetMinMaxT(ray, &ttmin, &ttmax) ) {
+      shaft.mSamples[i].mMinT = stmax;
+      shaft.mSamples[i].mMaxT = ttmin;
+      origin = ray.Extrap(stmax);
+      direction = ray.Extrap(ttmin) - origin;
+      // reinit the ray
+      ray.Init(origin, direction, Ray::LINE_SEGMENT);
+      if (!mKdTree->CastRay(ray))
+	return VISIBLE;
+    } else {
+      shaft.mSamples[i].mMaxT = -1.0;
+    }
+  }
+  return INVISIBLE;
+}
+
+int
 MutualVisibilitySampler::ComputeVisibility()
 {
 
-  vector<RayShaft *> samples;
-  ConstructInitialSamples(mSource, mTarget, samples);
-  ExportSamples(samples);
-
-  stack<RayShaft *> sampleStack;
+  vector<RayShaft *> shafts;
+  ConstructInitialSamples(mSource, mTarget, shafts);
+  ExportSamples(shafts);
+
+  stack<RayShaft *> shaftStack;
   
   
   
   Ray ray;
-  // now process the samples as long as we have something to do
-  while (!sampleStack.empty()) {
-    RayShaft *sample = sampleStack.top();
-    sampleStack.pop();
+  // now process the shafts as long as we have something to do
+  while (!shaftStack.empty()) {
+    RayShaft *shaft = shaftStack.top();
+    shaftStack.pop();
     
 //      // cast a new ray
 //      int triangleSplitEdge = SetupExtremalRay(sample, source, ray);
     
-//      if (!kdTree->CastRay(ray))
-//        return VISIBLE;
-    
-//      // generate 2 new samples
-//      RayShaft newSamples[2];
-//      sample.Split(triangleSplitEdge, ray, newSamples[0], newSamples[1]);
-//      for (i=0; i < 2; i++) {
-//        newSamples[i].ComputeError();
-//        if (newSamples[i].mError > solidAngleThreshold) {
-//  	sampleStack.push(newSamples[i]);
-//        }
-//      }
-//    }
-  }
-
-  for (int i=0; i < samples.size(); i++)
-    delete samples[i];
+    if (CastRays(*shaft) == VISIBLE)
+      return VISIBLE;
+    
+    //      // generate 2 new samples
+    //      RayShaft newSamples[2];
+    //      sample.Split(triangleSplitEdge, ray, newSamples[0], newSamples[1]);
+    //      for (i=0; i < 2; i++) {
+    //        newSamples[i].ComputeError();
+    //        if (newSamples[i].mError > solidAngleThreshold) {
+    //  	sampleStack.push(newSamples[i]);
+    //        }
+    //      }
+    //    }
+  }
+
+  for (int i=0; i < shafts.size(); i++)
+    delete shafts[i];
   return INVISIBLE;
 }
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 218)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 223)
@@ -91,142 +91,142 @@
   
   while (totalSamples < mTotalSamples)
-  {
-	  int passContributingSamples = 0;
-	  int passSampleContributions = 0;
-	  int passSamples = 0;
-	  int index = 0;
-
-	  for (i =0; i < objects.size(); i++) {
-		  KdNode *nodeToSample = NULL;
-		  Intersectable *object = objects[i];
-		  
-		  int pvsSize = object->mKdPvs.GetSize();
-      
-		  if (0 && pvsSize) {
-			  // mail all nodes from the pvs
-			  Intersectable::NewMail();
-			  KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
+    {
+      int passContributingSamples = 0;
+      int passSampleContributions = 0;
+      int passSamples = 0;
+      int index = 0;
+
+      for (i =0; i < objects.size(); i++) {
+	KdNode *nodeToSample = NULL;
+	Intersectable *object = objects[i];
+		  
+	int pvsSize = object->mKdPvs.GetSize();
+      
+	if (0 && pvsSize) {
+	  // mail all nodes from the pvs
+	  Intersectable::NewMail();
+	  KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
 			  
-			  for (; i != object->mKdPvs.mEntries.end(); i++) {
-				  KdNode *node = (*i).first;
-				  node->Mail();
-			  }
-
-			  int maxTries = 2*pvsSize;
-	
-			  for (int tries = 0; tries < 10; tries++) {
-				  index = RandomValue(0, pvsSize - 1);
-				  KdPvsData data;
-				  KdNode *node;
-				  object->mKdPvs.GetData(index, node, data);
-				  nodeToSample = mKdTree->FindRandomNeighbor(node, true);
-				  if (nodeToSample)
-					  break;
-			  }
-		  }
-      
-	      if (0 && pvsSize && pass == 50)  {
-			  // mail all nodes from the pvs
-			  Intersectable::NewMail();
-			  KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
-			  for (; i != object->mKdPvs.mEntries.end(); i++) {
-				  KdNode *node = (*i).first;
-				  node->Mail();
-			  }
-
-			  vector<KdNode *> invisibleNeighbors;
-			  // get all neighbors of all PVS nodes
-			  i = object->mKdPvs.mEntries.begin();
-
-			  for (; i != object->mKdPvs.mEntries.end(); i++) {
-				  KdNode *node = (*i).first;
-				  mKdTree->FindNeighbors(node, invisibleNeighbors, true);
-				  AxisAlignedBox3 box = object->GetBox();
-				  
-				  for (int j=0; j < invisibleNeighbors.size(); j++) 
-				  {
-					  int visibility = ComputeBoxVisibility(mKdTree,
-															box,
-															mKdTree->GetBox(invisibleNeighbors[j]),
-															1.0f);
-				  }
-				  // now rank all the neighbors according to probability that a new
-				  // sample creates some contribution
-			  }
-		  }
-
-		  for (int k=0; k < mSamplesPerPass; k++) {
-			  object->GetRandomSurfacePoint(point, normal);
-			  
-			  if (nodeToSample) {
-				  int maxTries = 5;
-				  
-				  for (int tries = 0; tries < maxTries; tries++) {
-					  direction = mKdTree->GetBox(nodeToSample).GetRandomPoint() - point;
-
-					  if (DotProd(direction, normal) > Limits::Small)
-						  break;
-				  }
-		
-				  if (tries == maxTries)
-					  direction = UniformRandomVector(normal);
-			  } 
-			  else
-				  direction = UniformRandomVector(normal);
-	
-			  // construct a ray
-			  SetupRay(ray, point, direction);
-			  mKdTree->CastRay(ray);
-
-			  if (i < pvsOut)
-				  rays[i].push_back(ray);
-	
-			  int sampleContributions = 0;
-	
-		  
-			  if (ray.leaves.size()) {
-				  sampleContributions += AddNodeSamples(object, ray, pass);
-	  
-				  if (ray.intersections.size()) {
-					  sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
-					  // check whether we can add this to the rays
-					  for (int j = 0; j < pvsOut; j++) {
-						  if (objects[j] == ray.intersections[0].mObject) {
-							  rays[j].push_back(ray);
-						  }
-					  }
-				  }
-
-				  passSamples++;
+	  for (; i != object->mKdPvs.mEntries.end(); i++) {
+	    KdNode *node = (*i).first;
+	    node->Mail();
+	  }
+
+	  int maxTries = 2*pvsSize;
+	
+	  for (int tries = 0; tries < 10; tries++) {
+	    index = RandomValue(0, pvsSize - 1);
+	    KdPvsData data;
+	    KdNode *node;
+	    object->mKdPvs.GetData(index, node, data);
+	    nodeToSample = mKdTree->FindRandomNeighbor(node, true);
+	    if (nodeToSample)
+	      break;
+	  }
+	}
+
+	
+	if (pvsSize && pass == 50 ) {
+	  // mail all nodes from the pvs
+	  Intersectable::NewMail();
+	  KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
+	  for (; i != object->mKdPvs.mEntries.end(); i++) {
+	    KdNode *node = (*i).first;
+	    node->Mail();
+	  }
+	
+	  vector<KdNode *> invisibleNeighbors;
+	  // get all neighbors of all PVS nodes
+	  i = object->mKdPvs.mEntries.begin();
+	  for (; i != object->mKdPvs.mEntries.end(); i++) {
+	    KdNode *node = (*i).first;
+	    mKdTree->FindNeighbors(node, invisibleNeighbors, true);
+	    AxisAlignedBox3 box = object->GetBox();
+	    for (int j=0; j < invisibleNeighbors.size(); j++) {
+	      int visibility = ComputeBoxVisibility(mKdTree,
+						    box,
+						    mKdTree->GetBox(invisibleNeighbors[j]),
+						    1.0f);
+	    
+	    }
+	    // now rank all the neighbors according to probability that a new
+	    // sample creates some contribution
+	  }
+	}
+
+      
+	for (int k=0; k < mSamplesPerPass; k++) {
+	  object->GetRandomSurfacePoint(point, normal);
+	
+	  if (nodeToSample) {
+	    int maxTries = 5;
+	  
+	    for (int tries = 0; tries < maxTries; tries++) {
+	      direction = mKdTree->GetBox(nodeToSample).GetRandomPoint() - point;
+	    
+	      if (DotProd(direction, normal) > Limits::Small)
+		break;
+	    }
+	  
+	    if (tries == maxTries)
+	      direction = UniformRandomVector(normal);
+	  } 
+	  else
+	    direction = UniformRandomVector(normal);
+	
+	  // construct a ray
+	  SetupRay(ray, point, direction);
+	  mKdTree->CastRay(ray);
+
+	  if (i < pvsOut)
+	    rays[i].push_back(ray);
+	
+	  int sampleContributions = 0;
+	
+		  
+	  if (ray.leaves.size()) {
+	    sampleContributions += AddNodeSamples(object, ray, pass);
+	  
+	    if (ray.intersections.size()) {
+	      sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
+	      // check whether we can add this to the rays
+	      for (int j = 0; j < pvsOut; j++) {
+		if (objects[j] == ray.intersections[0].mObject) {
+		  rays[j].push_back(ray);
+		}
+	      }
+	    }
+
+	    passSamples++;
 			
-				  if (sampleContributions) {
-					  passContributingSamples++;
-					  passSampleContributions += sampleContributions;
-				  }
-			  }
-		  }
+	    if (sampleContributions) {
+	      passContributingSamples++;
+	      passSampleContributions += sampleContributions;
+	    }
+	  }
 	}
-
-    totalSamples += passSamples;
-
-    //    if (pass>10)
-    //      HoleSamplingPass();
-    
-
-    pass++;
-    
-    int pvsSize = 0;
-    for (i=0; i < objects.size(); i++) {
-		Intersectable *object = objects[i];
-		pvsSize += object->mKdPvs.GetSize();
+      }
+
+      totalSamples += passSamples;
+
+      //    if (pass>10)
+      //      HoleSamplingPass();
+    
+
+      pass++;
+    
+      int pvsSize = 0;
+      for (i=0; i < objects.size(); i++) {
+	Intersectable *object = objects[i];
+	pvsSize += object->mKdPvs.GetSize();
+      }
+    
+      cout << "pass " << pass<<" : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
+      cout << "#totalSamples=" << totalSamples/1000 
+	   << "k   #sampleContributions=" << passSampleContributions << " (" 
+	   << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
+	   << pvsSize/(float)objects.size() << endl 
+	   << "avg ray contrib=" << passSampleContributions/(float)passContributingSamples << endl;
     }
-    
-	cout << "pass " << pass<<" : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
-	cout << "#totalSamples=" << totalSamples/1000 
-		 << "k   #sampleContributions=" << passSampleContributions << " (" 
-		 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
-		 << pvsSize/(float)objects.size() << endl 
-		 << "avg ray contrib=" << passSampleContributions/(float)passContributingSamples << endl;
-  }
 
   int totalPvsSize = mKdTree->CollectLeafPvs();
@@ -235,57 +235,57 @@
   //  HoleSamplingPass();
   if (1) {
-	  Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
-	  exporter->SetExportRayDensity(true);
-	  exporter->ExportKdTree(*mKdTree);
-	  delete exporter;
+    Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
+    exporter->SetExportRayDensity(true);
+    exporter->ExportKdTree(*mKdTree);
+    delete exporter;
   }
   
   bool exportRays = false;
   if (exportRays) {
-	  Exporter *exporter = NULL;
-	  exporter = Exporter::GetExporter("sample-rays.x3d");
-	  exporter->SetWireframe();
-	  exporter->ExportKdTree(*mKdTree);
-
-	  for (i=0; i < pvsOut; i++) 
-		  exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
-	  exporter->SetFilled();
-	  
-	  delete exporter;
+    Exporter *exporter = NULL;
+    exporter = Exporter::GetExporter("sample-rays.x3d");
+    exporter->SetWireframe();
+    exporter->ExportKdTree(*mKdTree);
+
+    for (i=0; i < pvsOut; i++) 
+      exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
+    exporter->SetFilled();
+	  
+    delete exporter;
   }
 
   if (1) {
-	  for (int k=0; k < pvsOut; k++) {
-		  Intersectable *object = objects[k];
-		  char s[64];
-		  sprintf(s, "sample-pvs%04d.x3d", k);
-		  Exporter *exporter = Exporter::GetExporter(s);
-		  exporter->SetWireframe();
-		  KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
-		  
-		  Intersectable::NewMail();
-		  
-		  // avoid adding the object to the list
-		  object->Mail();
-		  ObjectContainer visibleObjects;
-		  for (; i != object->mKdPvs.mEntries.end(); i++) {
-			  KdNode *node = (*i).first;
-			  exporter->ExportBox(mKdTree->GetBox(node));
-			  mKdTree->CollectObjects(node, visibleObjects);
-		  }
-      
-		  exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
-		  exporter->SetFilled();
-
-		  for (int j = 0; j < visibleObjects.size(); j++)
-			  exporter->ExportIntersectable(visibleObjects[j]);
-	
-		  Material m;
-		  m.mDiffuseColor = RgbColor(1, 0, 0);
-		  exporter->SetForcedMaterial(m);
-		  exporter->ExportIntersectable(object);
-      
-		  delete exporter;
-	  }
+    for (int k=0; k < pvsOut; k++) {
+      Intersectable *object = objects[k];
+      char s[64];
+      sprintf(s, "sample-pvs%04d.x3d", k);
+      Exporter *exporter = Exporter::GetExporter(s);
+      exporter->SetWireframe();
+      KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
+		  
+      Intersectable::NewMail();
+		  
+      // avoid adding the object to the list
+      object->Mail();
+      ObjectContainer visibleObjects;
+      for (; i != object->mKdPvs.mEntries.end(); i++) {
+	KdNode *node = (*i).first;
+	exporter->ExportBox(mKdTree->GetBox(node));
+	mKdTree->CollectObjects(node, visibleObjects);
+      }
+      
+      exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
+      exporter->SetFilled();
+
+      for (int j = 0; j < visibleObjects.size(); j++)
+	exporter->ExportIntersectable(visibleObjects[j]);
+	
+      Material m;
+      m.mDiffuseColor = RgbColor(1, 0, 0);
+      exporter->SetForcedMaterial(m);
+      exporter->ExportIntersectable(object);
+      
+      delete exporter;
+    }
   }
   
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Rectangle3.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Rectangle3.cpp	(revision 223)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Rectangle3.cpp	(revision 223)
@@ -0,0 +1,38 @@
+#include "Rectangle3.h"
+
+
+void
+Rectangle3::Split(const int axis,
+		  Rectangle3 &r1,
+		  Rectangle3 &r2
+		  ) const
+{
+  if (axis==0) {
+    Vector3 v1 = (mVertices[0] + mVertices[1])*0.5f;
+    Vector3 v2 = (mVertices[2] + mVertices[3])*0.5f;
+    
+    r1.mVertices[0] = mVertices[0];
+    r1.mVertices[1] = v1;
+    r1.mVertices[2] = v2;
+    r1.mVertices[3] = mVertices[3];
+
+    r2.mVertices[0] = v1;
+    r2.mVertices[1] = mVertices[1];
+    r2.mVertices[2] = mVertices[2];
+    r2.mVertices[3] = v2;
+  } else {
+    Vector3 v1 = (mVertices[0] + mVertices[3])*0.5f;
+    Vector3 v2 = (mVertices[1] + mVertices[2])*0.5f;
+    
+    r1.mVertices[0] = mVertices[0];
+    r1.mVertices[1] = mVertices[1];
+    r1.mVertices[2] = v2;
+    r1.mVertices[3] = v1;
+    
+    r2.mVertices[0] = v1;
+    r2.mVertices[1] = v2;
+    r2.mVertices[2] = mVertices[2];
+    r2.mVertices[3] = mVertices[3];
+  }
+  
+}
