void TSShapeLoader::computeBounds(Box3F& bounds)
{
   // Compute the box that encloses the model geometry
   bounds = Box3F::Invalid;

   // Use bounds node geometry if present
   if ( boundsNode && boundsNode->getNumMesh() )
   {
      for (S32 iMesh = 0; iMesh < boundsNode->getNumMesh(); iMesh++)
      {
         AppMesh* mesh = boundsNode->getMesh( iMesh );
         if ( !mesh )
            continue;

         Box3F meshBounds;
         mesh->computeBounds( meshBounds );
         if ( meshBounds.isValidBox() )
            bounds.intersect( meshBounds );
      }
   }
   else
   {
      // Compute bounds based on all geometry in the model
      for (S32 iMesh = 0; iMesh < appMeshes.size(); iMesh++)
      {
         AppMesh* mesh = appMeshes[iMesh];
         if ( !mesh )
            continue;

         Box3F meshBounds;
         mesh->computeBounds( meshBounds );
         if ( meshBounds.isValidBox() )
            bounds.intersect( meshBounds );
      }
   }
}
void ColladaShapeLoader::computeBounds(Box3F& bounds)
{
   TSShapeLoader::computeBounds(bounds);

   // Check if the model origin needs adjusting
   if ( bounds.isValidBox() &&
       (ColladaUtils::getOptions().adjustCenter ||
        ColladaUtils::getOptions().adjustFloor) )
   {
      // Compute shape offset
      Point3F shapeOffset = Point3F::Zero;
      if ( ColladaUtils::getOptions().adjustCenter )
      {
         bounds.getCenter( &shapeOffset );
         shapeOffset = -shapeOffset;
      }
      if ( ColladaUtils::getOptions().adjustFloor )
         shapeOffset.z = -bounds.minExtents.z;

      // Adjust bounds
      bounds.minExtents += shapeOffset;
      bounds.maxExtents += shapeOffset;

      // Now adjust all positions for root level nodes (nodes with no parent)
      for (S32 iNode = 0; iNode < shape->nodes.size(); iNode++)
      {
         if ( !appNodes[iNode]->isParentRoot() )
            continue;

         // Adjust default translation
         shape->defaultTranslations[iNode] += shapeOffset;

         // Adjust animated translations
         for (S32 iSeq = 0; iSeq < shape->sequences.size(); iSeq++)
         {
            const TSShape::Sequence& seq = shape->sequences[iSeq];
            if ( seq.translationMatters.test(iNode) )
            {
               for (S32 iFrame = 0; iFrame < seq.numKeyframes; iFrame++)
               {
                  S32 index = seq.baseTranslation + seq.translationMatters.count(iNode)*seq.numKeyframes + iFrame;
                  shape->nodeTranslations[index] += shapeOffset;
               }
            }
         }
      }
   }
}
示例#3
0
bool EditTSCtrl::processCameraQuery(CameraQuery * query)
{
   if(mDisplayType == DisplayTypePerspective)
   {
      query->ortho = false;
   }
   else
   {
      query->ortho = true;
   }

   if (getCameraTransform(&query->cameraMatrix))
   {
      query->farPlane = gClientSceneGraph->getVisibleDistance() * smVisibleDistanceScale;
      query->nearPlane = gClientSceneGraph->getNearClip();
      query->fov = mDegToRad(smCamFOV);

      if(query->ortho)
      {
         MatrixF camRot(true);
         const F32 camBuffer = 1.0f;
         Point3F camPos = query->cameraMatrix.getPosition();

         F32 isocamplanedist = 0.0f;
         if(mDisplayType == DisplayTypeIsometric)
         {
            const RectI& vp = GFX->getViewport();
            isocamplanedist = 0.25 * vp.extent.y * mSin(mIsoCamAngle);
         }

         // Calculate the scene bounds
         Box3F sceneBounds;
         computeSceneBounds(sceneBounds);

         if(!sceneBounds.isValidBox())
         {
            sceneBounds.maxExtents = camPos + smMinSceneBounds;
            sceneBounds.minExtents = camPos - smMinSceneBounds;
         }
         else
         {
            query->farPlane = getMax(smMinSceneBounds.x * 2.0f, (sceneBounds.maxExtents - sceneBounds.minExtents).len() + camBuffer * 2.0f + isocamplanedist);
         }

         mRawCamPos = camPos;
         camPos += mOrthoCamTrans;

         switch(mDisplayType)
         {
            case DisplayTypeTop:
               camRot.setColumn(0, Point3F(1.0, 0.0,  0.0));
               camRot.setColumn(1, Point3F(0.0, 0.0, -1.0));
               camRot.setColumn(2, Point3F(0.0, 1.0,  0.0));
               camPos.z = getMax(camPos.z + smMinSceneBounds.z, sceneBounds.maxExtents.z + camBuffer);
               break;

            case DisplayTypeBottom:
               camRot.setColumn(0, Point3F(1.0,  0.0,  0.0));
               camRot.setColumn(1, Point3F(0.0,  0.0,  1.0));
               camRot.setColumn(2, Point3F(0.0, -1.0,  0.0));
               camPos.z = getMin(camPos.z - smMinSceneBounds.z, sceneBounds.minExtents.z - camBuffer);
               break;

            case DisplayTypeFront:
               camRot.setColumn(0, Point3F(-1.0,  0.0,  0.0));
               camRot.setColumn(1, Point3F( 0.0, -1.0,  0.0));
               camRot.setColumn(2, Point3F( 0.0,  0.0,  1.0));
               camPos.y = getMax(camPos.y + smMinSceneBounds.y, sceneBounds.maxExtents.y + camBuffer);
               break;

            case DisplayTypeBack:
               camRot.setColumn(0, Point3F(1.0,  0.0,  0.0));
               camRot.setColumn(1, Point3F(0.0,  1.0,  0.0));
               camRot.setColumn(2, Point3F(0.0,  0.0,  1.0));
               camPos.y = getMin(camPos.y - smMinSceneBounds.y, sceneBounds.minExtents.y - camBuffer);
               break;

            case DisplayTypeLeft:
               camRot.setColumn(0, Point3F( 0.0, -1.0,  0.0));
               camRot.setColumn(1, Point3F( 1.0,  0.0,  0.0));
               camRot.setColumn(2, Point3F( 0.0,  0.0,  1.0));
               camPos.x = getMin(camPos.x - smMinSceneBounds.x, sceneBounds.minExtents.x - camBuffer);
               break;

            case DisplayTypeRight:
               camRot.setColumn(0, Point3F( 0.0,  1.0,  0.0));
               camRot.setColumn(1, Point3F(-1.0,  0.0,  0.0));
               camRot.setColumn(2, Point3F( 0.0,  0.0,  1.0));
               camPos.x = getMax(camPos.x + smMinSceneBounds.x, sceneBounds.maxExtents.x + camBuffer);
               break;

            case DisplayTypeIsometric:
               camPos.z = sceneBounds.maxExtents.z + camBuffer + isocamplanedist;
               MatrixF angle(EulerF(mIsoCamAngle, 0, 0));
               MatrixF rot(mIsoCamRot);
               camRot.mul(rot, angle);
               break;
         }

         query->cameraMatrix = camRot;
         query->cameraMatrix.setPosition(camPos);
         query->fov = mOrthoFOV;
      }

      smCamMatrix = query->cameraMatrix;
      smCamMatrix.getColumn(3,&smCamPos);
      smCamOrtho = query->ortho;
      smCamNearPlane = query->nearPlane;

      return true;
   }
   return false;
}