//------------------------------------------------------------------------------------------------ bool AnimatedMeshToShapeConverter::getOrientedBox(unsigned char bone, const Ogre::Vector3 &bonePosition, const Ogre::Quaternion &boneOrientation, Ogre::Vector3 &box_afExtent, Ogre::Vector3 *box_akAxis, Ogre::Vector3 &box_kCenter) { unsigned int vertex_count; Ogre::Vector3 *vertices; if (!getBoneVertices(bone, vertex_count, vertices, bonePosition)) { return false; } box_kCenter = Ogre::Vector3::ZERO; { for (unsigned int c = 0 ; c < vertex_count; ++c) { box_kCenter += vertices[c]; } const Ogre::Real invVertexCount = 1.0 / vertex_count; box_kCenter *= invVertexCount; } Ogre::Quaternion orient = boneOrientation; orient.ToAxes(box_akAxis); // Let C be the box center and let U0, U1, and U2 be the box axes. Each // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2. The // following code computes min(y0), max(y0), min(y1), max(y1), min(y2), // and max(y2). The box center is then adjusted to be // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 + // 0.5*(min(y2)+max(y2))*U2 Ogre::Vector3 kDiff (vertices[1] - box_kCenter); Ogre::Real fY0Min = kDiff.dotProduct(box_akAxis[0]), fY0Max = fY0Min; Ogre::Real fY1Min = kDiff.dotProduct(box_akAxis[1]), fY1Max = fY1Min; Ogre::Real fY2Min = kDiff.dotProduct(box_akAxis[2]), fY2Max = fY2Min; for (unsigned int i = 2; i < vertex_count; ++i) { kDiff = vertices[i] - box_kCenter; const Ogre::Real fY0 = kDiff.dotProduct(box_akAxis[0]); if (fY0 < fY0Min) { fY0Min = fY0; } else if (fY0 > fY0Max) { fY0Max = fY0; } const Ogre::Real fY1 = kDiff.dotProduct(box_akAxis[1]); if (fY1 < fY1Min) { fY1Min = fY1; } else if (fY1 > fY1Max) { fY1Max = fY1; } const Ogre::Real fY2 = kDiff.dotProduct(box_akAxis[2]); if (fY2 < fY2Min) { fY2Min = fY2; } else if (fY2 > fY2Max) { fY2Max = fY2; } } box_afExtent.x = (0.5f) * (fY0Max - fY0Min); box_afExtent.y = (0.5f) * (fY1Max - fY1Min); box_afExtent.z = (0.5f) * (fY2Max - fY2Min); box_kCenter += (0.5f * (fY0Max+fY0Min)) * box_akAxis[0] + (0.5f * (fY1Max+fY1Min)) * box_akAxis[1] + (0.5f * (fY2Max+fY2Min)) * box_akAxis[2]; box_afExtent *= 2.0f; return true; }