/// <summary> /// Generar OBB a partir de AABB /// </summary> /// <param name="aabb">BoundingBox</param> /// <returns>OBB generado</returns> public static TgcBoundingOrientedBox computeFromAABB(TgcBoundingAxisAlignBox aabb) { return(computeFromAABB(aabb.toStruct()).toClass()); }
/// <summary> /// Calcular OBB a partir de un conjunto de puntos. /// Prueba todas las orientaciones entre initValues y endValues, saltando de angulo en cada intervalo segun step /// Continua recursivamente hasta llegar a un step menor a 0.01f /// </summary> /// <returns></returns> private static OBBStruct computeFromPointsRecursive(TGCVector3[] points, TGCVector3 initValues, TGCVector3 endValues, float step) { var minObb = new OBBStruct(); var minVolume = float.MaxValue; var minInitValues = TGCVector3.Empty; var minEndValues = TGCVector3.Empty; var transformedPoints = new TGCVector3[points.Length]; float x, y, z; x = initValues.X; while (x <= endValues.X) { y = initValues.Y; var rotX = FastMath.ToRad(x); while (y <= endValues.Y) { z = initValues.Z; var rotY = FastMath.ToRad(y); while (z <= endValues.Z) { //Matriz de rotacion var rotZ = FastMath.ToRad(z); var rotM = TGCMatrix.RotationYawPitchRoll(rotY, rotX, rotZ); TGCVector3[] orientation = { new TGCVector3(rotM.M11, rotM.M12, rotM.M13), new TGCVector3(rotM.M21, rotM.M22, rotM.M23), new TGCVector3(rotM.M31, rotM.M32, rotM.M33) }; //Transformar todos los puntos a OBB-space for (var i = 0; i < transformedPoints.Length; i++) { transformedPoints[i].X = TGCVector3.Dot(points[i], orientation[0]); transformedPoints[i].Y = TGCVector3.Dot(points[i], orientation[1]); transformedPoints[i].Z = TGCVector3.Dot(points[i], orientation[2]); } //Obtener el AABB de todos los puntos transformados var aabb = TgcBoundingAxisAlignBox.computeFromPoints(transformedPoints); //Calcular volumen del AABB var extents = aabb.calculateAxisRadius(); extents = TGCVector3.Abs(extents); var volume = extents.X * 2 * extents.Y * 2 * extents.Z * 2; //Buscar menor volumen if (volume < minVolume) { minVolume = volume; minInitValues = new TGCVector3(x, y, z); minEndValues = new TGCVector3(x + step, y + step, z + step); //Volver centro del AABB a World-space var center = aabb.calculateBoxCenter(); center = center.X * orientation[0] + center.Y * orientation[1] + center.Z * orientation[2]; //Crear OBB minObb.center = center; minObb.extents = extents; minObb.orientation = orientation; } z += step; } y += step; } x += step; } //Recursividad en mejor intervalo encontrado if (step > 0.01f) { minObb = computeFromPointsRecursive(points, minInitValues, minEndValues, step / 10f); } return(minObb); }