Пример #1
0
        /// <summary>
        /// Transforma el BondingBox en base a una matriz de transformación.
        /// Esto implica escalar, rotar y trasladar.
        /// El procedimiento es mas costoso que solo hacer scaleTranslate().
        /// Se construye un nuevo BoundingBox en base a los puntos extremos del original
        /// más la transformación pedida.
        /// Si el BoundingBox se transformó y luego se llama a scaleTranslate(), se respeta
        /// la traslación y la escala, pero la rotación se va a perder.
        /// </summary>
        /// <param name="transform"></param>
        public void transform(Matrix transform)
        {
            //Transformar vertices extremos originales
            Vector3[] corners    = computeCorners(pMinOriginal, pMaxOriginal);
            Vector3[] newCorners = new Vector3[corners.Length];
            for (int i = 0; i < corners.Length; i++)
            {
                newCorners[i] = TgcVectorUtils.transform(corners[i], transform);
            }

            //Calcular nuevo BoundingBox en base a extremos transformados
            TgcBoundingBox newBB = TgcBoundingBox.computeFromPoints(newCorners);

            //actualizar solo pMin y pMax, pMinOriginal y pMaxOriginal quedan sin ser transformados
            pMin = newBB.pMin;
            pMax = newBB.pMax;

            dirtyValues = true;
        }
Пример #2
0
        /// <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);
        }