@ament - your PM space is full, can you clear some
All - will post once I have this figured out, ament has been helping me via PM (It looks like i'm loading doodad sets from the MODF chunk that I shouldn't be)
Edit: Does anyone know how you determine which doodad sets you should include/exclude? I know that the door is in set 1, but I don't know how to determine when I should/shouldn't load a doodad set.
0 should always be loaded, but how do i determine when to ignore others?
---------- Post added at 05:38 PM ---------- Previous post was at 04:15 PM ----------
Thanks for the help everyone, ament steered me in the right direction. Here is my new loadObjectReferences function. Basically instead of loading EVERY referenced doodad, it only loads the doodad sets mentioned for the given MODS chunk.
Code:
- (void)loadObjectReferences:(Obj0)obj0 andIndices:(Indices32_t *)indices andVertices:(Vertices_t *)vertices andNormals:(Normals_t *)normals{
// get doodads/WMOs of ADT
const ObjectReferences_t &obj_refs = obj0.getObjectRefs();
for ( ObjectReferences_t::const_iterator ref = obj_refs.begin(); ref != obj_refs.end(); ++ref ){
// get unique doodads here, notice: you can speed things up if you buffer
// already loaded objects here :)
for ( int d = 0; d < ref->doodadIndices.size(); d++ ) {
Doodad_s doodad;
obj0.getDoodad( ref->doodadIndices[d], &doodad );
// find unique identifier in map, only one uid can be present
UidMap_t::iterator found = _uid_map.find( doodad.info.uid );
// unique identifier not found: insert UID in map
if ( found == _uid_map.end() ) {
_uid_map.insert( UidMap_t::value_type( doodad.info.uid, (void*)0 ) );
BufferS_t doodad_buf;
_mpqHandler->getFile( doodad.name, &doodad_buf );
// doodad buffers
Indices32_t m2_i;
Vertices_t m2_v;
Normals_t m2_n;
// if doodad geometry is present: transform and merge
if ( [self getDoodadGeometry:doodad.name andIndices:&m2_i andVertices:&m2_v andNormals:&m2_n] ){
// bring vertices to our coordinate system
transformVertices( doodad.info.pos, doodad.info.rot, doodad.info.scale / 1024.0f, &m2_v );
mergeIndices( m2_i, vertices->size(), indices );
mergeVertices( m2_v, vertices );
mergeNormals( m2_n, normals );
}
}
}
// get unique WMOs here, same thing as above: buffer -> +speed !
for ( int d = 0; d < ref->wmoIndices.size(); d++ ) {
uint32_t obj_index = ref->wmoIndices[d];
// get wmo from object file
Wmo_s wmo;
obj0.getWmo( obj_index, &wmo );
// find WMOs UID in our map
UidMap_t::iterator found = _uid_map.find( wmo.info.uid );
// unique identifier not found: insert UID in map
if ( found == _uid_map.end() ) {
_uid_map.insert( UidMap_t::value_type( wmo.info.uid, (void*)0 ) );
BufferS_t wmo_buf;
_mpqHandler->getFile( wmo.name, &wmo_buf );
// parse wmo data
WmoModel wmo_model( wmo_buf );
wmo_model.loadGroups( wmo.name, *_mpqHandler );
// wmo buffers
Indices32_t wmo_i;
Vertices_t wmo_v;
Normals_t wmo_n;
wmo_model.getIndices( &wmo_i ); // this is what we hate... lulszoersz
wmo_model.getVertices( &wmo_v );
wmo_model.getNormals( &wmo_n );
// bring vertices to our coordinate system
const ModfChunk_s::WmoInfo_s &info = obj0.wmoInfo()[obj_index];
transformVertices( info.pos, info.rot, 1.0f, &wmo_v );
mergeIndices( wmo_i, vertices->size(), indices );
mergeVertices( wmo_v, vertices );
mergeNormals( wmo_n, normals );
const ModsChunk_s::DoodadSets_t &mods_doodads = wmo_model.getModsChunk().doodadSets;
// then we really don't care about this doodad set!
if ( info.doodadSet >= mods_doodads.size() ){
NSLog(@" invalid set %d (Size: %lu)", info.doodadSet, mods_doodads.size());
continue;
}
// this is the doodad set we care about! (info.doodadSet)
const ModsChunk_s::DoodadSet_s doodadsets_t = mods_doodads.at(info.doodadSet);
const ModnChunk_s &modn_chunk = wmo_model.getModnChunk();
// only load these!
for ( int i = doodadsets_t.firstIndex; i < doodadsets_t.firstIndex + doodadsets_t.numDoodads; i++ ){
const ModdChunk_s::DoodadInformation_s modd_infos = wmo_model.getModdChunk().infos.at(i);
// doodad name
std::string doodad_name( (const char*)&modn_chunk.doodadNames[modd_infos.id] );
// no name? or nil? weird
if ( int(doodad_name.size() - 4) < 0 ){
NSLog(@"Fail?");
NSLog(@" %s", doodad_name.c_str());
continue;
}
doodad_name.replace( doodad_name.size() - 4, 4, ".M2" );
BufferS_t doodad_buf;
_mpqHandler->getFile( doodad_name, &doodad_buf );
// load doodad if buffer has data
if ( doodad_buf.size() ) {
M2 m2( doodad_buf );
Indices32_t m2_i;
Vertices_t m2_v;
Normals_t m2_n;
m2.getBoundingIndices( &m2_i );
m2.getBoundingVertices( &m2_v );
m2.getBoundingNormals( &m2_n );
// interior doodads have to be transformed by their parent WMO's
// transformation first
for ( int i = 0; i < m2_v.size(); i++ ) {
glm::vec3 &vtx = m2_v[i];
vtx = glm::rotate( modd_infos.rotation, vtx ) * modd_infos.scale + modd_infos.position;
}
// now transform by
transformVertices( info.pos, info.rot, 1.0f, &m2_v );
mergeIndices( m2_i, vertices->size(), indices );
mergeVertices( m2_v, vertices );
mergeNormals( m2_n, normals );
}
}
}
}
}
}
Note: You do have to edit wowmodel.cpp to actually store ModsChunk_s:

oodadSet_s, out of the box wowmapper just skips the data. Enjoy! I hope it's correct
