Вопрос

I have this class for AABB wich i foun in internet and it have worked for when mesh moves, but when i rotate mesh of course it stops working, also i have noted that it has a transform function so i think this is what i have to use so it works after i rotate the mesh, but im a little bit new with matrix and i don't know how to use it:

    #ifndef AABB_H
    #define AABB_H

    class aabb {
    public:
    aabb() { min.x = min.y = min.z = 1e24f; max.x = max.y = max.z = -1e24f; }
    aabb &operator =(const aabb &a) { min = a.min; max = a.max; return *this; }

    vec3d min, max;

    vec3d center() { return ((min + max) * 0.5f); }

    void empty() { min.x = min.y = min.z = 1e24f; max.x = max.y = max.z = -1e24f; }
    void add(const vec3d &pnt) {
        if (pnt.x < min.x) min.x = pnt.x;
        if (pnt.x > max.x) max.x = pnt.x;
        if (pnt.y < min.y) min.y = pnt.y;
        if (pnt.y > max.y) max.y = pnt.y;
        if (pnt.z < min.z) min.z = pnt.z;
        if (pnt.z > max.z) max.z = pnt.z;
    }
    void transform(const mat3x3 &m, const vec3d &trans) {
        vec3d oldmin = min, oldmax = max;
        min = max = trans;
        if (m.m11 > 0.0f) { min.x += m.m11 * oldmin.x; max.x += m.m11 * oldmax.x; }
            else { min.x += m.m11 * oldmax.x; max.x += m.m11 * oldmin.x; }
        if (m.m12 > 0.0f) { min.y += m.m21 * oldmin.x; max.y += m.m21 * oldmax.x; }
            else { min.y += m.m21 * oldmax.x; max.y += m.m21 * oldmin.x; }
        if (m.m13 > 0.0f) { min.z += m.m31 * oldmin.x; max.z += m.m31 * oldmax.x; }
            else { min.z += m.m31 * oldmax.x; max.z += m.m31 * oldmin.x; }
        if (m.m21 > 0.0f) { min.x += m.m12 * oldmin.y; max.x += m.m12 * oldmax.y; }
            else { min.x += m.m12 * oldmax.y; max.x += m.m12 * oldmin.y; }
        if (m.m22 > 0.0f) { min.y += m.m22 * oldmin.y; max.y += m.m22 * oldmax.y; }
            else { min.y += m.m22 * oldmax.y; max.y += m.m22 * oldmin.y; }
        if (m.m23 > 0.0f) { min.z += m.m32 * oldmin.y; max.z += m.m32 * oldmax.y; }
            else { min.z += m.m32 * oldmax.y; max.z += m.m32 * oldmin.y; }
        if (m.m31 > 0.0f) { min.x += m.m13 * oldmin.z; max.x += m.m13 * oldmax.z; }
            else { min.x += m.m13 * oldmax.z; max.x += m.m13 * oldmin.z; }
        if (m.m32 > 0.0f) { min.y += m.m23 * oldmin.z; max.y += m.m23 * oldmax.z; }
            else { min.y += m.m23 * oldmax.z; max.y += m.m23 * oldmin.z; }
        if (m.m33 > 0.0f) { min.z += m.m33 * oldmin.z; max.z += m.m33 * oldmax.z; }
            else { min.z += m.m33 * oldmax.z; max.z += m.m33 * oldmin.z; }
    }

    bool contains(const vec3d &a) { return (a.x >= min.x) && (a.x <= max.x) && (a.y >= min.y) && (a.y <= max.y) && (a.z >= min.z) && (a.z <= max.z); }
    vec3d closest(const vec3d &a) {
        vec3d r;
        if (a.x < min.x) r.x = min.x;
            else if (a.x > max.x) r.x = max.x;
                else r.x = a.x;

        if (a.y < min.y) r.y = min.y;
            else if (a.y > max.y) r.y = max.y;
                else r.y = a.y;

        if (a.z < min.z) r.z = min.z;
            else if (a.z > max.z) r.z = max.z;
                else r.z = a.z;
        return r;
    }
    };
    #endif

Also as aditional data i just want to rotate mesh in Y-axix because it's a naval game.

Thanks for answers.

Это было полезно?

Решение

I recognize that code from the book 3d math primer for graphics and game development, but it's not exactly the same. I can see that the translation part would work but not any rotation. The trans is meant to be the translation part of your matrix. In the book, a bounding box is passed in as well to the method. In the code you have found, this is removed an replaced with saving the old min and max values to start with in the method. The code will expand the min and max values to infinity (just adding on and on and on). The code is optimized so that not all 8 corner points are transformed but instead utilizing how a point is transformed by a matrix and figuring out which one of these would have the smallest value after the transformation. The trick to minimize the entire sum is to minimize each of the products individually for each of the 9 elements in the matrix.

Something like this works for me...

public void add(float[] p) {
    if (p[0] < mOriginalMin[0]) {
        mOriginalMin[0] = p[0];
    }
    if (p[0] > mOriginalMax[0]) {
        mOriginalMax[0] = p[0];
    }
    if (p[1] < mOriginalMin[1]) {
        mOriginalMin[1] = p[1];
    }
    if (p[1] > mOriginalMax[1]) {
        mOriginalMax[1] = p[1];
    }
    if (p[2] < mOriginalMin[2]) {
        mOriginalMin[2] = p[2];
    }
    if (p[2] > mOriginalMax[2]) {
        mOriginalMax[2] = p[2];
    }
}

public void transform(Matrix44 mat) {
    /** Get the translation part */
    mCurrMin[0] = mCurrMax[0] = mat.m[12];
    mCurrMin[1] = mCurrMax[1] = mat.m[13];
    mCurrMin[2] = mCurrMax[2] = mat.m[14];

    if (mat.m[0] > 0) {
        mCurrMin[0] += mat.m[0] * mOriginalMin[0];
        mCurrMax[0] += mat.m[0] * mOriginalMax[0];
     } else {
        mCurrMin[0] += mat.m[0] * mOriginalMax[0];
        mCurrMax[0] += mat.m[0] * mOriginalMin[0];
     }
            .....etc etc.

Другие советы

I think that 'trans' means translate not transform (hint: there are no matrix operations being performed here). Speaking of transforms and matrices - there is your answer. If the object is rotated, translated, or scaled then you should get its global (world) matrix and multiply the min and max by it. Then recalculate your center.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top