Skip to content

Commit

Permalink
Model: Fix model aspect-correct scaling; cleanup
Browse files Browse the repository at this point in the history
All shared global resource instances are now owned by ResourceSystem.
Everything appears to be working as expected. All that remains to be
done is some further cleanup before this branch is ready to be merged
back to the master.
  • Loading branch information
danij-deng committed Dec 3, 2013
1 parent 640b178 commit 4e59067
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 67 deletions.
15 changes: 7 additions & 8 deletions doomsday/client/include/resource/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ typedef uint modelid_t;
/// Special value used to signify an invalid model id.
#define NOMODELID 0

/**
* 3D model resource.
* @ingroup resource
*/
class Model
{
public:
Expand Down Expand Up @@ -150,6 +154,8 @@ class Model
* Attempt to load a new model resource from the specified @a file.
*
* @param aspectScale Optionally apply y-aspect scaling.
*
* @return The new Model (if any). Ownership is given to the caller.
*/
static Model *loadFromFile(de::FileHandle &file, float aspectScale = 1);

Expand Down Expand Up @@ -198,13 +204,6 @@ class Model
*/
Frame &frame(int number) const;

/**
* Append a new animation frame to the model.
*
* @param newFrame Ownership is given to the model.
*/
void addFrame(Frame *newFrame);

/**
* Returns the total number of model animation frames.
*/
Expand Down Expand Up @@ -299,7 +298,7 @@ class Model
DetailLevels const &lods() const;

/// @todo Refactor away.
QBitArray const vertexUsage() const;
QBitArray const &lodVertexUsage() const;

private:
DENG2_PRIVATE(d)
Expand Down
104 changes: 46 additions & 58 deletions doomsday/client/src/resource/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ using namespace de;

bool Model::DetailLevel::hasVertex(int number) const
{
return model.vertexUsage().testBit(number * model.lodCount() + level);
return model.lodVertexUsage().testBit(number * model.lodCount() + level);
}

void Model::Frame::bounds(Vector3f &retMin, Vector3f &retMax) const
Expand Down Expand Up @@ -100,19 +100,6 @@ static bool readMd2Header(de::FileHandle &file, md2_header_t &hdr)
return true;
}

/// @todo We only really need to read the magic bytes and the version here.
static bool recogniseMd2(de::FileHandle &file)
{
md2_header_t hdr;
size_t initPos = file.tell();
// Seek to the start of the header.
file.seek(0, SeekSet);
bool result = (readMd2Header(file, hdr) && LONG(hdr.magic) == MD2_MAGIC);
// Return the stream to its original position.
file.seek(initPos, SeekSet);
return result;
}

//
#define DMD_MAGIC 0x4D444D44 ///< "DMDM" = Doomsday/Detailed MoDel Magic

Expand All @@ -136,18 +123,6 @@ static bool readHeaderDmd(de::FileHandle &file, dmd_header_t &hdr)
return true;
}

static bool recogniseDmd(de::FileHandle &file)
{
dmd_header_t hdr;
size_t initPos = file.tell();
// Seek to the start of the header.
file.seek(0, SeekSet);
bool result = (readHeaderDmd(file, hdr) && LONG(hdr.magic) == DMD_MAGIC);
// Return the stream to its original position.
file.seek(initPos, SeekSet);
return result;
}

static void *allocAndLoad(de::FileHandle &file, int offset, int len)
{
uint8_t *ptr = (uint8_t *) M_Malloc(len);
Expand All @@ -167,12 +142,12 @@ DENG2_PIMPL(Model)
Flags flags;
Skins skins;
Frames frames;
int numVertices; ///< Total number of vertices in the model.
int numVertices;

DetailLevels lods; ///< Level of detail information.
QBitArray vertexUsage; ///< Denotes used vertices for each level of detail.
DetailLevels lods;
QBitArray lodVertexUsage;

uint modelId; ///< Unique id of the model (in the repository).
uint modelId; ///< In the repository.

Instance(Public *i)
: Base(i)
Expand Down Expand Up @@ -211,11 +186,10 @@ DENG2_PIMPL(Model)
*/
static Model *loadMd2(de::FileHandle &file, float aspectScale)
{
// Read the header.
// Determine whether this appears to be a MD2 model.
md2_header_t hdr;
bool readHeaderOk = readMd2Header(file, hdr);
DENG2_ASSERT(readHeaderOk);
DENG2_UNUSED(readHeaderOk); // should this be checked?
if(!readMd2Header(file, hdr)) return 0;
if(LONG(hdr.magic) != MD2_MAGIC) return 0;

Model *mdl = new Model;

Expand Down Expand Up @@ -257,7 +231,7 @@ DENG2_PIMPL(Model)
}
}

mdl->addFrame(frame); // takes owernship
mdl->d->frames.append(frame);
}
M_Free(frameData);

Expand Down Expand Up @@ -378,11 +352,10 @@ DENG2_PIMPL(Model)
*/
static Model *loadDmd(de::FileHandle &file, float aspectScale)
{
// Read the header.
// Determine whether this appears to be a DMD model.
dmd_header_t hdr;
bool readHeaderOk = readHeaderDmd(file, hdr);
DENG2_ASSERT(readHeaderOk);
DENG2_UNUSED(readHeaderOk); // should this be checked?
if(!readHeaderDmd(file, hdr)) return 0;
if(LONG(hdr.magic) != DMD_MAGIC) return 0;

// Read the chunks.
dmd_chunk_t chunk;
Expand Down Expand Up @@ -467,7 +440,7 @@ DENG2_PIMPL(Model)
}
}

mdl->addFrame(frame);
mdl->d->frames.append(frame);
}
M_Free(frameData);

Expand Down Expand Up @@ -526,15 +499,15 @@ DENG2_PIMPL(Model)
}

// Determine vertex usage at each LOD level.
mdl->d->vertexUsage.resize(info.numVertices * info.numLODs);
mdl->d->vertexUsage.fill(false);
mdl->d->lodVertexUsage.resize(info.numVertices * info.numLODs);
mdl->d->lodVertexUsage.fill(false);

for(int i = 0; i < info.numLODs; ++i)
for(int k = 0; k < lodInfo[i].numTriangles; ++k)
for(int m = 0; m < 3; ++m)
{
int vertexIndex = SHORT(triangles[i][k].vertexIndices[m]);
mdl->d->vertexUsage.setBit(vertexIndex * info.numLODs + i);
mdl->d->lodVertexUsage.setBit(vertexIndex * info.numLODs + i);
}

delete [] lodInfo;
Expand All @@ -549,20 +522,20 @@ DENG2_PIMPL(Model)

static Model *interpretDmd(de::FileHandle &hndl, float aspectScale)
{
if(recogniseDmd(hndl))
if(Model *mdl = loadDmd(hndl, aspectScale))
{
LOG_VERBOSE("Interpreted \"" + NativePath(hndl.file().composePath()).pretty() + "\" as a DMD model.");
return loadDmd(hndl, aspectScale);
return mdl;
}
return 0;
}

static Model *interpretMd2(de::FileHandle &hndl, float aspectScale)
{
if(recogniseMd2(hndl))
if(Model *mdl = loadMd2(hndl, aspectScale))
{
LOG_VERBOSE("Interpreted \"" + NativePath(hndl.file().composePath()).pretty() + "\" as a MD2 model.");
return loadMd2(hndl, aspectScale);
return mdl;
}
return 0;
}
Expand Down Expand Up @@ -647,6 +620,30 @@ Model::Model(Flags flags) : d(new Instance(this))
setFlags(flags, de::ReplaceFlags);
}

static bool recogniseDmd(de::FileHandle &file)
{
dmd_header_t hdr;
size_t initPos = file.tell();
// Seek to the start of the header.
file.seek(0, SeekSet);
bool result = (readHeaderDmd(file, hdr) && LONG(hdr.magic) == DMD_MAGIC);
// Return the stream to its original position.
file.seek(initPos, SeekSet);
return result;
}

static bool recogniseMd2(de::FileHandle &file)
{
md2_header_t hdr;
size_t initPos = file.tell();
// Seek to the start of the header.
file.seek(0, SeekSet);
bool result = (readMd2Header(file, hdr) && LONG(hdr.magic) == MD2_MAGIC);
// Return the stream to its original position.
file.seek(initPos, SeekSet);
return result;
}

bool Model::recognise(de::FileHandle &hndl) //static
{
if(recogniseDmd(hndl)) return true;
Expand Down Expand Up @@ -752,15 +749,6 @@ Model::Frame &Model::frame(int number) const
throw MissingFrameError("Model::frame", "Invalid frame number " + String::number(number) + ", valid range is " + Rangei(0, d->frames.count()).asText());
}

void Model::addFrame(Frame *newFrame)
{
if(!newFrame) return;
if(!d->frames.contains(newFrame))
{
d->frames.append(newFrame);
}
}

Model::Frames const &Model::frames() const
{
return d->frames;
Expand Down Expand Up @@ -839,7 +827,7 @@ int Model::vertexCount() const
return d->numVertices;
}

QBitArray const Model::vertexUsage() const
QBitArray const &Model::lodVertexUsage() const
{
return d->vertexUsage;
return d->lodVertexUsage;
}
2 changes: 1 addition & 1 deletion doomsday/client/src/resource/resourcesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ DENG2_PIMPL(ResourceSystem)
// Attempt to load it in now.
QScopedPointer<de::FileHandle> hndl(&fileSystem().openFile(foundPath, "rb"));

mdl = Model::loadFromFile(*hndl);
mdl = Model::loadFromFile(*hndl, modelAspectMod);

// We're done with the file.
fileSystem().releaseFile(hndl->file());
Expand Down

0 comments on commit 4e59067

Please sign in to comment.