Author Topic: Mesh rotation  (Read 2528 times)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1806
    • zapsolution
Mesh rotation
« on: July 31, 2019, 10:45:46 am »
Mike

I would like to use a new parameter to perform individual mesh rotation without changing the original x, y, z axis rotation,
in order to bypass the code in red below.

void calcMeshBounds() { // MLL 01-01-2019: much better bounding sphere radius calc
    MobjMesh* pMesh;
    BBOX pAABB;
    float rX, rY, rZ;
    long nI, nJ, nK;

    for (nI = 0; nI < gM.numberOfMeshes; nI++) {
        // ML 01-18-2018: choose REASONABLY large/small initialization values!
        float rxMax = -1000000.0f;
        float ryMax = rxMax;
        float rzMax = rxMax;

        float rxMin = 1000000.0f;
        float ryMin = rxMin;
        float rzMin = rxMin;

        float x = 0.f, y = 0.f, z = 0.f;
        float *p;

        pMesh = &gtm_meshes[nI];
        pAABB = pMesh->meshAABB;
        for (nJ = 0; nJ < pMesh->triangleCount * 3; nJ++) {
            nK = gnm_indexBuffer[pMesh->startIndex + nJ];
            p = gtm_vertexBuffer[nK].position;

            rX = p[0]; rY = p[1]; rZ = p[2];

            x += rX; y += rY; z += rZ;

            if (rX < rxMin) { rxMin = rX; } else if (rX > rxMax) { rxMax = rX; }
            if (rY < ryMin) { ryMin = rY; } else if (rY > ryMax) { ryMax = rY; }
            if (rZ < rzMin) { rzMin = rZ; } else if (rZ > rzMax) { rzMax = rZ; }

        }

        // MLL 10-18-2018: axis aligned bounding box (a.k.a. AABB)
        pAABB.min[0] = rxMin; pAABB.min[1] = ryMin; pAABB.min[2] = rzMin;
        pAABB.max[0] = rxMax; pAABB.max[1] = ryMax; pAABB.max[2] = rzMax;

        float* mc = pMesh->meshCenter;
        mc[0] = (rxMin + rxMax) * 0.5f;
        mc[1] = (ryMin + ryMax) * 0.5f;
        mc[2] = (rzMin + rzMax) * 0.5f;

        float* mcd = pMesh->meshCentroid;
        mcd[0] = x / --nJ; mcd[1] = y / nJ; mcd[2] = z / nJ;

        // MLL 12-20-2018: AABB vertices (mb is in fact mb[8][3])
        float* mb = &pMesh->meshBox[0][0];
        mb[0]  = rxMax; mb[1]  = ryMax; mb[2]  = rzMax;
        mb[3]  = rxMin; mb[4]  = ryMax; mb[5]  = rzMax;
        mb[6]  = rxMin; mb[7]  = ryMin; mb[8]  = rzMax;
        mb[9]  = rxMax; mb[10] = ryMin; mb[11] = rzMax;
        mb[12] = rxMax; mb[13] = ryMin; mb[14] = rzMin;
        mb[15] = rxMax; mb[16] = ryMax; mb[17] = rzMin;
        mb[18] = rxMin; mb[19] = ryMax; mb[20] = rzMin;
        mb[21] = rxMin; mb[22] = ryMin; mb[23] = rzMin;

        // MLL 01-01-2019: still this isn't the tightest possible mesh bounding sphere yet... :(
        float d[3], *mr = &pMesh->meshRadius;
        *mr = 0.0f;
        for (nJ = 0; nJ < pMesh->triangleCount * 3; nJ++) { // find max distance squared from center to farthest vertex
            nK = gnm_indexBuffer[pMesh->startIndex + nJ];

            p = gtm_vertexBuffer[nK].position;
            d[0] = p[0] - mc[0]; d[1] = p[1] - mc[1]; d[2] = p[2] - mc[2];

            float dSq = d[0] * d[0] + d[1] * d[1] + d[2] * d[2]; // distance squared
            if (dSq > *mr) // comparing distances squared is much faster than taking square roots in each iteration
                *mr = dSq;
        }
        *mr = sqrtf(*mr); // finally, take square root !!! fast_sqrtf() YIELDS SPHERES LARGER THAN NECESSARY !!!
    }
}


What do you think would be best?



« Last Edit: July 31, 2019, 11:36:14 am by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Mesh rotation
« Reply #1 on: July 31, 2019, 03:50:39 pm »
Patrice,

I don't exactly see what you mean. The code in red has no direct relation to mesh rotation. It relates to determining i) mesh vertices' extreme coord values that will form up the mesh tightest bounding box and sphere; ii) mesh geometric center, i.e. the center of its bounding box and sphere; and iii) mesh centroid, i.e. its center of "physical gravity" that differs from its geometric center if the mesh shape is irregular rather than symmetrical.

The x, y, z vars used here aren't directly related to any mesh parameters, whether static or dynamic, and are mere temporary value accumulators.

Individual mesh rotation/swinging/rocking is always done respective to its centroid (which is the same as its center if the mesh is absolutely center-symmetric) directly in the FFP and PPL render procs with the following code:
Code: [Select]
........
            // Test rotation // MLL 06-11-2018:
            if (bDoRotate) {
                float m[16], *c = pMesh->meshCentroid; // cache
                float *r = pMaterial->rotate, a = pMaterial->rotangle; // ditto
                float c0 = c[0], c1 = c[1], c2 = c[2]; // ditto
                float r1 = r[1], r2 = r[2], r3 = r[3]; // ditto
                glPushMatrix();
                glGetFloatv(GL_MODELVIEW_MATRIX, m);
                mtxTranslate(m, c0, c1, c2);
                if (r1) mtxRotate(m, r1, 0, 0, a);
                if (r2) gP.bAxesSwapped ? mtxRotate(m, 0, 0, r2, a) : mtxRotate(m, 0, r2, 0, a);
                if (r3) gP.bAxesSwapped ? mtxRotate(m, 0, r3, 0, a) : mtxRotate(m, 0, 0, r3, a);
                mtxTranslate(m, -c0, -c1, -c2);
                glLoadMatrixf(m);
            }
........

This is the only scheme we can use to basically displace the meshes with respect to one another on the fly without fully rigging the model with a skeleton and then performing matrix and/or quaternion calc on every bone, and thus indirectly, on every vertex in every mesh of the entire model. Given the immense size of the majority of our models, we will not be able to animate them in real time through rigging because of the enormous amount of calc it would involve, except for the simplest models like game characters or smaller scenery objects.

Please try to re-formulate your desire, if you can, to make it clearer for me and evaluate if it's feasible or not in principle. :)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1806
    • zapsolution
Re: Mesh rotation
« Reply #2 on: July 31, 2019, 05:11:21 pm »
Ok, here is an example to help you understand what i wan to achieve.

1 - Run the project as is with the current OR code.

2 - Then, run the project with the OR code shown in red disabled (rem it out)

Indeed, i want to have all the meshes using the same rotation center point, but with distinct rotation speed and their original center preserved like what you get in case 2.
« Last Edit: July 31, 2019, 05:13:37 pm by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Mesh rotation
« Reply #3 on: July 31, 2019, 06:47:09 pm »
There will be NOTHING to preserve if you just omit this code! There will simply be no mesh  bounding boxes, nor centers, nor centroids! Just one big crazy nil, nothing, emptiness -- null and void!

See below how what you're suggesting breaks up what we now have... :o :-[ :'( :'( :'(
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Mesh rotation
« Reply #4 on: July 31, 2019, 07:26:49 pm »
You will not be able to make your chaotic asymmetric meshes rotate around an arbitrary common point. Each of them can only rotate around their own center of mass (centroid) which tends towards the space populated by their respective vertices and away from the empty space that lies on the opposite side.

Use solid concentric planes and balls for individual meshes and emulate asymmetric pies, sectors, strips, hollow lattices, grills, whatever with alpha maps applied to the meshes. Then you'll be able to get what you want using our existing toolset.

Just as simple as that.
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1806
    • zapsolution
Re: Mesh rotation
« Reply #5 on: July 31, 2019, 07:51:51 pm »
Obviously you didn't understood me.

I do not want to change anything in the existing code, just add an extra parameter to disable the code in red on demand when i want to perform things like in the attached video.

Quote
Use solid concentric planes and balls for individual meshes and emulate asymmetric pies, sectors, strips, hollow lattices, grills, whatever with alpha maps applied to the meshes. Then you'll be able to get what you want using our existing toolset.
I know how to emulate this, but it is much extra work when the individual mesh components are themselves discontinued 3D surfaces.

Note: hopefully the download speed should be restored by tomorrow, wait and see  ::)

BTW did you checked the AlphaMask code you asked me?
« Last Edit: July 31, 2019, 08:00:24 pm by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Mesh rotation
« Reply #6 on: July 31, 2019, 10:19:18 pm »
You should be fully aware of the following two major issues:

0. Your nullified astro-rotation is only feasible if all the rotating meshes are concentric resp. the model center of origin. An attempt to move them elsewhere, or rotate the meshes that are concentric resp. any other point in model space, will send the meshes flying all over the screen in complete chaos. Thus it is one and only special case of a myriad possible mesh animations.

1. Your remming out the red portion of calcMeshBounds() for the animated meshes renders them inferior to the model's other static meshes. Having no centers, bounding boxes and other relevant data, they cannot be effectively used for early visibility culling (my pending TODO to ease up the rendering pipeline), collision detection, physics, etc.

If you still insist on being given such an opportunity, you should do the following:

1. Increase the size of rotate[] array in the material structure definition (globals.h) to rotate[8] and do not forget to clear it with 0 in all the places where a material structure is initialized. There are two such places in mobj.h: Mobj_importMaterials() and Mobj_importGeometryFirstPass().

2. Leave calcMeshBounds() alone the way it is now.

3. Use rotate[7] as a 0.f/1.f flag to indicate the mesh is supposed to rotate model-centrically regardless of its centroid.

4. Add yet one more %f to the case else if (strcmp(szBuffer, "#rotate") == 0) format string in Mobj_importMaterials() (mobj.h) to read the new flag into rotate[7].

5. Use the following code in both drawUsingFixedFuncPipeline() and drawUsingProgrammablePipeline() (renderers.h):
........
            // Test rotation // MLL 06-11-2018:
            if (bDoRotate) {
                float nullCentroid[3] = { 0 };
                float m[16], *c = pMaterial->rotate[7] != 0.0f ? nullCentroid : pMesh->meshCentroid;
// cache
                float *r = pMaterial->rotate, a = pMaterial->rotangle; // ditto
                float c0 = c[0], c1 = c[1], c2 = c[2]; // ditto
                float r1 = r[1], r2 = r[2], r3 = r[3]; // ditto
                glPushMatrix();
                glGetFloatv(GL_MODELVIEW_MATRIX, m);
                mtxTranslate(m, c0, c1, c2);
                if (r1) mtxRotate(m, r1, 0, 0, a);
                if (r2) gP.bAxesSwapped ? mtxRotate(m, 0, 0, r2, a) : mtxRotate(m, 0, r2, 0, a);
                if (r3) gP.bAxesSwapped ? mtxRotate(m, 0, r3, 0, a) : mtxRotate(m, 0, 0, r3, a);
                mtxTranslate(m, -c0, -c1, -c2);
                glLoadMatrixf(m);
            }
........


6. .........................................................................

7. Profit! ;D

(Tell me if those mods are doing for you what you want. I haven't yet tested them here.)


Re. AlphaMask: It works for me the way it is (standalone) but it needs some adjustments for use in ObjReader. I don't currently have enough time nor health to finalize it. The weather has been very unstable here in recent two weeks or so, which is making me seriously unwell... :(
« Last Edit: August 01, 2019, 03:19:48 am by Michael Lobko-Lobanovsky »
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1806
    • zapsolution
Re: Mesh rotation
« Reply #7 on: August 01, 2019, 08:58:27 am »
Quote
The weather has been very unstable here in recent two weeks or so, which is making me seriously unwell... :(
I am very sad to read this, and i sympathize with you.

As a matter of feedback these two weeks where also bad for me, because of the heat, and the cherry on the cake was during the night of last friday-saturday, because a local storm was causing the fall down of a sequoia branch on my roof, and a water flow in my bedroom. Forcing me to climb on the roof in the dark night, and under an heavy rain to put a couple of new tiles, and a plastic sheet to close another hole... that was terrible.

I shall test the code changes you suggested and will let you know how it works, once done.

Added:
Perfect, the changes work exactly like what i want, and should let me do things like these
https://www.behance.net/gallery/30283093/Sci-fi-interface-HUD


« Last Edit: August 01, 2019, 10:02:38 am by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Mesh rotation
« Reply #8 on: August 01, 2019, 02:56:25 pm »
Oh, what a terrible nightmare (literally) you had! I'm really sorry to hear that! I used to own a country cottage in the past, and I can imagine very well what it looked and felt like! :o

Re. behance dot net, I should stress once again: using the new option, you'll be able to rotate only those meshes that are strictly concentric with the model origin [0,0,0]. The other animated meshes that are spatially displaced resp. [0,0,0] will have to be rotated/rocked the old way. And yes, both methods may be used concurrently in the same model, the only difference being the trailing 0.f/1.f flag in the #rotate meta.

I'm glad I was able to help you out with this at almost no expense. :)

P.S. As an afterthought inspired by behance, we can also easily add individual mesh scaling animation (not sure if translational animation could also be implemented so easily though...) 8)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1806
    • zapsolution
Re: Mesh rotation
« Reply #9 on: August 01, 2019, 06:28:33 pm »
My friend, the download speed should be restored

Please confirm that it is now good for you.
« Last Edit: August 01, 2019, 07:56:31 pm by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Mesh rotation
« Reply #10 on: August 01, 2019, 07:45:16 pm »
My friend,

Yes, the download speed seems to be restored for me! :D

But pinging (even with the correct address -- yours has a typo!) times out for me on all tries... :o
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1806
    • zapsolution
Re: Mesh rotation
« Reply #11 on: August 04, 2019, 09:18:11 am »
Quote
As an afterthought inspired by behance, we can also easily add individual mesh scaling animation (not sure if translational animation could also be implemented so easily though...)

Here is a new Sketchfab model, that would be a good candidate to check animation(s).
I did put the .fbx, in case you want to edit the meshes into Blender.

Currently this model, as is, can't use the OR #rotate
« Last Edit: August 04, 2019, 11:29:21 am by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Mesh rotation
« Reply #12 on: August 04, 2019, 12:18:41 pm »
Hehe thank you very much! Very interesting! :D

BTW the original .FBX cannot be loaded into Blender as-is because its format is too old.

I used the Autodesk FBX Converter to upgrade it to FBX 2013 to be able to load it.
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1806
    • zapsolution
Re: Mesh rotation
« Reply #13 on: August 04, 2019, 04:52:44 pm »
Here is a quick OR version...
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Mesh rotation
« Reply #14 on: August 04, 2019, 05:18:22 pm »
Not bad at all! :D

And I think there's quite a bit more that's possible including what can be done with our sprites. :)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)