/// <summary> /// Convertir a struct /// </summary> public OBBStruct toStruct() { var obbStruct = new OBBStruct(); obbStruct.center = Position; obbStruct.orientation = orientation; obbStruct.extents = extents; return obbStruct; }
/// <summary> /// Generar OBB a partir de AABB /// </summary> /// <param name="aabb">BoundingBox</param> /// <returns>OBB generado</returns> public static OBBStruct computeFromAABB(TgcBoundingAxisAlignBox.AABBStruct aabb) { var obb = new OBBStruct(); obb.extents = (aabb.max - aabb.min) * 0.5f; obb.center = aabb.min + obb.extents; obb.orientation = new[] { new TGCVector3(1, 0, 0), TGCVector3.Up, new TGCVector3(0, 0, 1) }; return obb; }
/// <summary> /// Convertir a struct /// </summary> public OBBStruct toStruct() { OBBStruct obbStruct = new OBBStruct(); obbStruct.center = center; obbStruct.orientation = orientation; obbStruct.extents = extents; return(obbStruct); }
/// <summary> /// Generar OBB a partir de AABB /// </summary> /// <param name="aabb">BoundingBox</param> /// <returns>OBB generado</returns> public static TgcObb.OBBStruct computeFromAABB(TgcBoundingBox.AABBStruct aabb) { OBBStruct obb = new OBBStruct(); obb.extents = (aabb.max - aabb.min) * 0.5f; obb.center = aabb.min + obb.extents; obb.orientation = new Vector3[] { new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1) }; return(obb); }
/// <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(Vector3[] points, Vector3 initValues, Vector3 endValues, float step) { var minObb = new OBBStruct(); var minVolume = float.MaxValue; var minInitValues = Vector3.Empty; var minEndValues = Vector3.Empty; var transformedPoints = new Vector3[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 = Matrix.RotationYawPitchRoll(rotY, rotX, rotZ); Vector3[] orientation = { new Vector3(rotM.M11, rotM.M12, rotM.M13), new Vector3(rotM.M21, rotM.M22, rotM.M23), new Vector3(rotM.M31, rotM.M32, rotM.M33) }; //Transformar todos los puntos a OBB-space for (var i = 0; i < transformedPoints.Length; i++) { transformedPoints[i].X = Vector3.Dot(points[i], orientation[0]); transformedPoints[i].Y = Vector3.Dot(points[i], orientation[1]); transformedPoints[i].Z = Vector3.Dot(points[i], orientation[2]); } //Obtener el AABB de todos los puntos transformados var aabb = TgcBoundingBox.computeFromPoints(transformedPoints); //Calcular volumen del AABB var extents = aabb.calculateAxisRadius(); extents = TgcVectorUtils.abs(extents); var volume = extents.X * 2 * extents.Y * 2 * extents.Z * 2; //Buscar menor volumen if (volume < minVolume) { minVolume = volume; minInitValues = new Vector3(x, y, z); minEndValues = new Vector3(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); }
/// <summary> /// Convertir a struct /// </summary> public OBBStruct toStruct() { OBBStruct obbStruct = new OBBStruct(); obbStruct.center = center; obbStruct.orientation = orientation; obbStruct.extents = extents; return obbStruct; }
/// <summary> /// Generar OBB a partir de AABB /// </summary> /// <param name="aabb">BoundingBox</param> /// <returns>OBB generado</returns> public static TgcObb.OBBStruct computeFromAABB(TgcBoundingBox.AABBStruct aabb) { OBBStruct obb = new OBBStruct(); obb.extents = (aabb.max - aabb.min) * 0.5f; obb.center = aabb.min + obb.extents; obb.orientation = new Vector3[] { new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1) }; return obb; }
/// <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(Vector3[] points, Vector3 initValues, Vector3 endValues, float step) { OBBStruct minObb = new OBBStruct(); float minVolume = float.MaxValue; Vector3 minInitValues = Vector3.Empty; Vector3 minEndValues = Vector3.Empty; Vector3[] transformedPoints = new Vector3[points.Length]; float x, y, z; x = initValues.X; while(x <= endValues.X) { y = initValues.Y; float rotX = FastMath.ToRad(x); while (y <= endValues.Y) { z = initValues.Z; float rotY = FastMath.ToRad(y); while (z <= endValues.Z) { //Matriz de rotacion float rotZ = FastMath.ToRad(z); Matrix rotM = Matrix.RotationYawPitchRoll(rotY, rotX, rotZ); Vector3[] orientation = new Vector3[]{ new Vector3(rotM.M11, rotM.M12, rotM.M13), new Vector3(rotM.M21, rotM.M22, rotM.M23), new Vector3(rotM.M31, rotM.M32, rotM.M33) }; //Transformar todos los puntos a OBB-space for (int i = 0; i < transformedPoints.Length; i++) { transformedPoints[i].X = Vector3.Dot(points[i], orientation[0]); transformedPoints[i].Y = Vector3.Dot(points[i], orientation[1]); transformedPoints[i].Z = Vector3.Dot(points[i], orientation[2]); } //Obtener el AABB de todos los puntos transformados TgcBoundingBox aabb = TgcBoundingBox.computeFromPoints(transformedPoints); //Calcular volumen del AABB Vector3 extents = aabb.calculateAxisRadius(); extents = TgcVectorUtils.abs(extents); float volume = extents.X * 2 * extents.Y * 2 * extents.Z * 2; //Buscar menor volumen if (volume < minVolume) { minVolume = volume; minInitValues = new Vector3(x, y, z); minEndValues = new Vector3(x + step, y + step, z + step); //Volver centro del AABB a World-space Vector3 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; }