various HMP related MDL7 SDK questions

Posted By: HeelX

various HMP related MDL7 SDK questions - 12/07/11 23:18

Hi,

I am currently working with the MDL7 SDK and I am writing HMP7 files. Two questions (prepare for further questions in the near future smile):

1.) In the demo application for writing a HMP7 file, you are setting the member flags of HMP5_HEADER once to 1 and once to 0. I noticed no difference, but from the function name you use there, I guess it has something to do with a complete planar surface... is this flag really used?? What effect does it have?

2.) It seems to me that the name parameter of the ::Skin method has no effect with HMPs... I do the following:

Code:
// determine skin type
int skinType = s->isExtern ? M7SKINTYP_EXT_FILE : 0;

// create new skin
hmp.Skin(skinType, "test123");



So, it should have the name "test123" in the skin manager, but when I open the generated HMP in MED, it is named "Skin0" and I even can't edit it. Is this done by purpose or a bug?
Posted By: HeelX

Re: HMP5_HEADER flags, skin name - 12/08/11 00:03

3.) Can you imagine any reason, why MED shows the HMP correct with external texture, but when I load it in the engine I see nothing? Here is my source:

Code:
// save skins
if (h->numSkins > 0)
{
    for (int i = 0; i < h->numSkins; i++)
    {
        // get skin
        HmpSkin* s = (h->skins)[i];

        // determine skin type
        int skinType = 0;
        {
            if (s->isExtern)
                skinType = M7SKINTYP_EXT_FILE;

            if (s->mat)
                skinType |= M7SKINTYP_MATERIAL;
        }

        // create new skin
        hmp.Skin(skinType, s->name);

        // prepare skin size parameters
        int sizex = s->isExtern ? (int)strlen(s->externFile)+1 : 0;
        int sizey = s->isExtern ? 1 : 0;
        int bypp = s->isExtern ? 1 : 0;
        bool mips = false;

        // set skin size
        hmp.SkinSize(sizex, sizey, bypp, mips);

        // skin bits
        if (s->isExtern)
            hmp.SkinBits((BYTE*)s->externFile, 0, 0, 0);

        // material, if any
        if (s->mat)
        {
            // convert bgr var colors from material to rgb float triplets
            float diffuse[3], ambient[3], specular[3], emissive[3];
            rgbForBgrVar(diffuse, &(s->mat->diffuse_blue));
            rgbForBgrVar(ambient, &(s->mat->ambient_blue));
            rgbForBgrVar(specular, &(s->mat->specular_blue));
            rgbForBgrVar(emissive, &(s->mat->emissive_blue));

            // transfer rgb triplets to skin
            hmp.SkinMaterial(diffuse, ambient, specular, emissive, _FLOAT(s->mat->power));
        }

        // finish skin
        hmp.SkinDone();
    }
}



It is almost the same procedure you do as in the example. I also placed it before writing the height values, etc...???

[EDIT]

I only see an external texture in the engine, when I add in MED a new skin, while all faces are selected and I press "set skin"...?
Posted By: HeelX

various HMP related MDL7 SDK questions - 12/08/11 00:06

4.) Can you please explain .SkinBits, it is not very well documented.
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/08/11 11:02

3) FIXED

I messed up with the scale and offset transformation from world space to data space. This is how it is correctly done:

Code:
// get lowest and highest height
float lowest, highest;
hmp_minmaxz(h, &lowest, &highest);

// magnitude is height distance between lowest and highest
float magnitude = highest - lowest;

// z values have to be between 0...65535, so we have to set
// implicit scale and offset parameters

float lowerBound = 0.0f, upperBound = 65535.0f;

// scale
{
	hmp.Head().scale[0] = h->width / upperBound;
	hmp.Head().scale[1] = h->height / upperBound;
	hmp.Head().scale[2] = magnitude / upperBound;
}

// offset
{
	hmp.Head().scale_origin[0] = -h->width/2;
	hmp.Head().scale_origin[1] = -h->height/2;
	hmp.Head().scale_origin[2] = lowest;
}



My previous mi/max values were wrong, so it was so ackwardly stretched, that I didn't saw it.
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/09/11 17:25

5.) What means the M7SKINTYP_RGBFLAG flag?
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/11/11 20:10

6.) when I want to use a BMAP* in the engine as image, which I want to save as intern texture into a HMP, should I just write the RGB or RGBA data via SkinBits into a HMP or do I have to generate the next 3 mipmaps on my own and pass them as the next three parameters? What happens when I pass NULL?
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/11/11 20:12

7.) depending on 6.): how do I calculate the boolean for mips in .SkinSize? Is it always false for DDS and palette images? If it is for external textures: enforces it (during HMP loading in-engine) mipmap generation when it is true or prohibits mipmap generation when it is false? Is it always true for all other internal texture formats?
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/11/11 20:18

8.) if it is an internal DDS file, how do I calculate the dds file size which I obviously have to pass as width-parameter to SkinSize? If I loaded a DDS as BMAP* in-engine, how do I calculate it on-the-fly, can I use

Code:
long width,height; // original size of the bitmap
long bytespp; // original bytes per pixel (1..4)



from the BMAP struct for that?

9.) What happens if a DDS has mipmaps stored? Do I have to turn on the previously mentioned mips flag anywhere?
Posted By: jcl

Re: various HMP related MDL7 SDK questions - 12/13/11 15:20

Ok, I'll try to answer back to front:

9) DDS mipmaps have no mips flag and are handled automatically.
8) For DDS skins, bytespp = 1 and with = the DDS file size.
7) the mips flag means that 3 mipmaps are stored following the image, each with 1/4 the size.
6) You must generate the 3 mipmaps when you set the mips flag.
5) and 1) I have no idea.
3) The usual reason is a full transparent image.
2) Yes, skin names have no effect in a HMP.
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/13/11 16:26

Thank you very much for the answers! Though, some things are still not clear to me:

Quote:
8) For DDS skins, bytespp = 1 and with = the DDS file size.
What do you mean? That bytespp stores for DDS images the filesize? --> YES; bytespp stores the filesize.

Quote:
7) the mips flag means that 3 mipmaps are stored following the image, each with 1/4 the size.
What happens, if I leave it off: will the engine calculate then the mipmaps itself upon loading the HMP?

Quote:
5) and 1) I have no idea.
So, what are you doing in MED; are you just setting them to a default variable?
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/16/11 13:23

10) I was able to successfully embed DDS and 8888 BMAP's as interal skins. But I have trouble with files I loaded via bmap_create, which were saved as 24bit images. As I found this out, I also was not able to store 24bit images correctly in my HMP. If a BMAP has a 8888 format and bytespp is = 3, do I have to make a stripped copy of the byte* pixels array, while I skip every fourth values (=alpha) and pass this array to SkinBits instead of just b->pixels???
Posted By: jcl

Re: various HMP related MDL7 SDK questions - 12/16/11 13:36

As to the mipmaps, there's an engine function to calculate them, but of course it's faster when they are already stored in the HMP file. They also have better quality dependent on the filter that you use.

The image in the HMP file is stored in straight 888 format. Only when it's loaded in your video hardware, it gets a different format such as 8888.

As to the questions 1) and 5), I've forwarded them to the developer, who will answer them when he's back next week.
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/16/11 14:13

Thanks!

I found out, that I just have to correct the skin type and bytespp values, which I pass to .Skin and .SkinSize in the case that format is 8888 and bytespp is 3 -- I can always use the .pixels pointer.

[EDIT] Just for the record: if I create a bitmap during runtime and it is 8888, I can simply use finalbits (after locking) and if the size of the bmap is power of two; if it is 888 I have to do the stripping method I mentioned above (create array of 75% size and copy all contents from finalbits except every fourth element).
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/18/11 23:11

Hm, when I set the mips flag of .SkinSize to true and pass pixels like I am doing for the main texture (the mip textures are each 1/2 the size of the previous texture...), I can't load the terrain in MED and when I load it as entity in the engine, it is unbelievable stretched on the z-axis...? smile

[EDIT]

Tested it twice: once with generated textures and once with provided textures... no success, though tired
Posted By: jcl

Re: various HMP related MDL7 SDK questions - 12/19/11 14:04

If you upload that terrain, I can check what it wrong.

Here's the remaining info - I'll also add this to the documentation:

HMP5_HEADER::flags determines whether the terrain is a floor or a cave ceiling, i.e. if the normals point upwards or downwards.

And the M7SKINTYP_RGBFLAG differentiates between RGB and BGR bit order on 24 and 32 bit skin types.
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/20/11 20:31

Thank you!

Originally Posted By: jcl
If you upload that terrain, I can check what it wrong.


Yes, I will; tomorrow. A question in the meantime:


11) If terrain_chunk == 0 (terrains are'nt chunked): when is a terrain going to be valid? There are different information in the manual:
  • 'Entities' page: "Unchunked terrain is rendered just like a model, and must not exceed a size of 128x128 vertices." ... so, does this mean if it exceeds 16384 vertices or if either the x- or y- row/column vertices is greater than 128, the terrain cannot be unchunked? Like 130x128 or 128x130.
  • 'terrain_chunk' page: "Depending on the 3D hardware, the size of nonchunked terrain is normally limited to 65536 vertices" - do you really mean vertices or faces? So, if my total of vertices is greater than 65536, the terrain cannot be unchunked?
  • 'Updating' page: "Unchunked Terrain is not supported anymore. The Free and Extra versions also support chunked terrain." - so is every terrain chunked??? What happens if terrain_chunk is == 0 then???

Posted By: jcl

Re: various HMP related MDL7 SDK questions - 12/21/11 14:33

Yes, every terrain is chunked in A8. Unchunked terrain is not supported anymore and terrain_chunk must not be 0.
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 12/21/11 15:00

Ok! Then, maybe, you should clean up the statements about unchunked terrain in the manual - I guess it could be somehow confusing for beginners if they come across that stuff the first time.

Here is, by the way, the archive with the promised hmp's: http://www.christian-behrenberg.de/files/shared/a8/bugs/mips.rar

It contains two HMPs and 4 textures. The file "tile_mips_static.hmp" was created by loading the 4 bmps and using them as mipmap data sources; the file "tile_mips_dynamic.hmp" was created by creating consecutive smaller bitmaps from the passed internal BMAP*.

In both cases, "true" is passed for the mips parameter in .SkinSize(...) and BYTE* pointers are passed for the three mipmaps in .SkinBits(...).

For BMAP*'s, I wrote a function, that returns me a BYTE* pointer to the pixeldata. Here is the source:

Code:
BYTE* pixelsForBmap (BMAP* b, BOOL* locked, BYTE** stripped)
{
    BYTE* pixels = NULL;

    if (b && locked && stripped)
    {
        // if bmap was loaded from file, just take the (original) pixels
        if (b->pixels)
            pixels = b->pixels;
        else
        {
            // bmap was created during runtime, therefore no
            // "original" pixels are available

            // we need to lock image to access finalbits!

            bmap_lock(b, 0);
            *locked = true;

            // in the case of an 8888 image (BGRA), we can simply take
            // the finalbits

            if (b->bytespp == 4)
                pixels = (BYTE*)(b->finalbits);
            else
            {
                // problem: 24bit image is specified, but is stored internally
                // different. We have to extract the stuff!

                int n = b->width * b->height * 3;
                *stripped = (BYTE*)sys_malloc(sizeof(BYTE) * n);

                for (int i = 0; i < n; i++)
                    (*stripped)[i] = ((BYTE*)(b->finalbits))[((i / 3) * 4) + (i % 3)];

                pixels = (*stripped);
            }
        }
    }

    return(pixels);
}



The function behaviour is pretty selfexplanatory. If I create a stripped representation of the pixel data, the pointer references are set, so that I can handle such things in my circumstancing code, e.g. for cleanup or the like.

I use this function not only for mipmap BMAP's, but also for the main skin image. If mips is == false and therefore I pass NULL, NULL, NULL as mipmaps to SkinBits, everything is fine and the terrain can be loaded in MED and in the engine... --- So this is the reason why I did two test: because if my internal mipmap calculation is somehow broken, my passed BMAP's, loaded from file, must be correct, because the sizes are right and the function is proofed to be correct (on the main image before).

I hope these information are sufficient for you to find out what is going wrong here on my end smile and thank you very much for your time!!
Posted By: HeelX

Re: various HMP related MDL7 SDK questions - 01/12/12 08:15

Hi,
have you found the reason for my problems?

By the way, I now turned to loading hmp's from files. There is a code segment in the LoadHMP.cpp example file, which is executed in a case, which I don't understand:

Code:
int numv_x = (int) head->fnumverts_x;
int numv_y = head->numverts / numv_x;

...

float x_size = head->ftrisize_x * (numv_x - 1);
float y_size = head->ftrisize_y * (numv_y - 1); 
float x_step = x_size / (numv_x-1); 
float y_step = y_size / (numv_y-1); 

...

//'hmp.fr' == current frame data
if ( x_step == 0 || y_step == 0)
{
    float min_x = (float) hmp.fr->min.p_pos[0] * head->scale[0] + head->scale_origin[0];
    float min_y = (float) hmp.fr->min.p_pos[1] * head->scale[1] + head->scale_origin[1];
    
    float max_x = (float) hmp.fr->max.p_pos[0] * head->scale[0] + head->scale_origin[0];
    float max_y = (float) hmp.fr->max.p_pos[1] * head->scale[1] + head->scale_origin[1];
    
    x_size = (max_x-min_x);
    y_size = (max_y-min_y); 
    x_step = x_size / (numv_x - 1);
    y_step = y_size / (numv_y - 1);
}



The if-block is executed if and only if the header indicates no triangle size for x or y direction - but when is that the case? Is this code segment just a workaround for hmp files which were written in a wrong way by a user? Is it possible that the MDL7 SDK can do this also?
Posted By: jcl

Re: various HMP related MDL7 SDK questions - 01/13/12 11:17

I think this is just for catching wrong input data, such as terrain that only consists of 1 vertex. - I'll check your example in the next time.
© 2024 lite-C Forums