awaytools / awd-sdk

10 stars 8 forks source link

C++ SDK issues #3

Closed bboltz closed 10 years ago

bboltz commented 10 years ago

Hello,

I'm using the Away3D SDK C++, and I have encountered a couple of issues so far:

  1. The AWDMetaData class allocates its own memory for generator_name and generator_version, but I don't see it de-allocating this memory anywhere. The override_encoder_metadata() function doesn't attempt to delete any previous allocated memory.
  2. The Importer side is completely missing. The SDK doesn't import AWD files.

Thanks

bboltz commented 10 years ago

Another issue:

The C++ SDK only writes out 2.0 AWD files. However, the AwayBuilder Live Tool writes out 2.1 AWD files. I would like to see the SDK write out the same version as AwayBuilder = v2.1.

Version 2.1 has support normal maps and lightmaps, while v2.0 doesn't.

Thanks

bboltz commented 10 years ago

Another issue:

When exporting large meshes with verts/trigs greater than 65536, the AWDGeomUtil tool is not splitting the mesh into submeshes. It's writing out a single submesh with the vertex index field set to AWD_FIELD_UINT32.

By itself, I have no problem with it, but when I try to load this model into AwayBuilder Live Tool, it doesn't render the mesh properly. The mesh is deformed, vertices are pinned. I'm guessing it's ignoring the field type.

80prozent commented 10 years ago

Hey Bolt1

i am working on the c++ sdk (libawd) for some days now. excpect more changes/updates in the next days/weeks.

about your issues:

The AWDMetaData class allocates its own memory for generator_name and generator_version, but I don't see it de-allocating this memory anywhere. The override_encoder_metadata() function doesn't attempt to delete any previous allocated memory.

The Importer side is completely missing. The SDK doesn't import AWD files.

The C++ SDK only writes out 2.0 AWD files. However, the AwayBuilder Live Tool writes out 2.1 AWD files.

When exporting large meshes with verts/trigs greater than 65536, the AWDGeomUtil tool is not splitting the mesh into submeshes. It's writing out a single submesh with the vertex index field set to AWD_FIELD_UINT32.

bboltz commented 10 years ago

Thanks for the reply.

I'm looking at the AWD example files that come with away3d-examples-fp11 (MonsterHead.awd, PolarBear.awd, tictac.awd, etc...) and it seems there's a problem with their geometry data streams. All of the vertex index streams have their field set to AWD_FIELD_UINT32 (6), when it should be AWD_FIELD_UINT16 (5). These are all v2.0 files.

When I save these out using the AwayBuilder LiveTool, it sets the proper field type, AWD_FIELD_UINT16. The C++ SDK also sets the proper field type. However, the only problem with this is when you're exporting large files. Re-writing MonsterHead.awd with the C++ SDK will write out a proper field of AWD_FIELD_UINT32 with large indices. But, as I mentioned, the AwayBuilder LiveTool ignores it, and you get a mess.

So, all of the assets will be bugged if the LiveTool was changed to work correctly. :) Fixing geomUtil to split submeshes will temporarily fix the problem, but as long as the AWD loaders don't respect the field, the problem will still remain.

bboltz commented 10 years ago

BTW, thanks, I missed the Jan26 update. I downloaded the new SDK C++ and tried it out, but it crashed on me. It looks like the SDK is now writing out the metadata block, however, there are some memory bugs/leaks.

bboltz commented 10 years ago

Found another metadata bug:

this->encoder_name needs to be allocated with ASCIIZ null terminator. Otherwise, functions like strlen won't work properly. this->encoder_name = (char *)malloc(6+1);

You may want to check to see if snprintf is terminating the other string with NULL.

This line won't set a NULL terminator: memcpy(this->encoder_name, "libawd", 6); This is causing "libawd" to be written with a bad string length.

bboltz commented 10 years ago

My changes:

class AWDMetaData :
    public AWDBlock,
    public AWDAttrElement
{
    protected:
        char *encoder_name;
        char *encoder_version;
        void prepare_and_add_dependencies(AWDBlockList *);
        awd_uint32 calc_body_length(bool);
        void write_body(int, bool);

    public:
        AWDMetaData();
        ~AWDMetaData();     // ADDED
        char *generator_name;
        char *generator_version;

        void override_encoder_metadata(char *, char *);
};

AWDMetaData::AWDMetaData() :
    AWDBlock(METADATA),
    AWDAttrElement(),
    encoder_name(NULL),     // ADDED
    encoder_version(NULL),
    generator_name(NULL),
    generator_version(NULL)
{

    this->encoder_name = (char *)malloc(6+1);   // CHANGED
    memset(this->encoder_name, 0, (6+1));   // ADDED
    memcpy(this->encoder_name, "libawd", 6);

    this->encoder_version = (char *)malloc(255);
    memset(this->encoder_version, 0, 255);  // ADDED
    snprintf(this->encoder_version, 255, "%d.%d.%d%c",
             AWD::VERSION_MAJOR, AWD::VERSION_MINOR, AWD::VERSION_BUILD, AWD::VERSION_RELEASE);
}

// ADDED

AWDMetaData::~AWDMetaData() {

 if(this->generator_name) {
    free(this->generator_name);
    this->generator_name = NULL;
 }
 if(this->generator_version) {
    free(this->generator_version);
    this->generator_version = NULL;
 }

 if(this->encoder_name) {
    free(this->encoder_name);
    this->encoder_name = NULL;
 }
 if(this->encoder_version) {
    free(this->encoder_version);
    this->encoder_version = NULL;
 }
}

void
AWDMetaData::override_encoder_metadata(char *name, char *version)
{

 // ADDED

 if(this->encoder_name) {
    free(this->encoder_name);
    this->encoder_name = NULL;
 }
 if(this->encoder_version) {
    free(this->encoder_version);
    this->encoder_version = NULL;
 }

 this->encoder_name    = name;
 this->encoder_version = version;
}

AWD::~AWD()
{
    delete this->texture_blocks;
    delete this->cubetex_blocks;
    delete this->material_blocks;
    delete this->mesh_data_blocks;
    delete this->skeleton_blocks;
    delete this->skelanim_blocks;
    delete this->skelpose_blocks;
    delete this->uvanim_blocks;
    delete this->scene_blocks;
    delete this->namespace_blocks;

    if(this->metadata) {
       delete this->metadata;       // ADDED, this ok?
    }
}

void
AWD::set_metadata(AWDMetaData *block)
{

    if(this->metadata) {
       delete this->metadata;       // ADDED
       this->metadata = NULL;
    }

    this->metadata = block;
}
bboltz commented 10 years ago

Another issue: It looks like the updated SDK now writes out normal textures, but geomUtil still doesn't support vertex tangents. So, the normalmap won't render correctly without them.

But, I don't even know what format Away3D is using for vertex tangents? Is it a 3 or 4-float vector? I would think you would need at least two 3D vectors, tangent and bi-tangent. However, I only see one stream type, 5, for "vertex tangents".

80prozent commented 10 years ago

hey sorry for taken so long to reply i was working on a different part of the 3dsmax exporter over the last week, and only came back to the libawd two days ago...

i think you are 100% right about the field_type for the vertex-index-stream. i will see to fix this in the AWD2parser, so the field_type of the stream gets respected. i will take care to update this in the AWDEncoder too.

About the metadata and deconstructor bugs: i am quite new to c++, and havnt really looked at the deconstruction side of the libawd yet. for me this compiles for 2012. I didnt searched for bugs there yet. as mentioned previeous, thats on my to do. thanks for the changes you posted. i will review them and include them into my next update.

btw. i have been working a lot on the libawd in the past two days, and will commit a major refactor soon, including multimaterial export, splitting big meshes into subgeos, adding missing animation-blocks...

i will keep working on the libawd, so hopefully it will support all the awd2.1 stuff soon.

for the normal maps and the vertex-tangent data: i am not shure what the vertex-tangent data is really used for. i am only exporting vertex-normal-data and normal-maps. Away3d automaticly calculates Vertextangent-data (3-float-vector).

bboltz commented 10 years ago

No problem. Thanks for the updates!

80prozent commented 10 years ago

Hey I did a lot of changes to the AWD-SDK. For me, VC2010 does not show any memory leaks any more.