store imported geometry more compactly
parent
5452a0d30b
commit
02d6129df9
|
@ -31,36 +31,38 @@ class AbstractAnimationTrack {
|
|||
public:
|
||||
enum EType {
|
||||
EInvalid = 0,
|
||||
ELocationX, ELocationY, ELocationZ,
|
||||
EScaleX, EScaleY, EScaleZ,
|
||||
ELocationX, ELocationY, ELocationZ, ELocationXYZ,
|
||||
EScaleX, EScaleY, EScaleZ, EScaleXYZ,
|
||||
ERotationX, ERotationY, ERotationZ,
|
||||
ERotationQuat
|
||||
};
|
||||
|
||||
/// Return the type of this track
|
||||
inline EType getType() const { return m_type; }
|
||||
protected:
|
||||
AbstractAnimationTrack(EType type) : m_type(type) { }
|
||||
|
||||
protected:
|
||||
EType m_type;
|
||||
};
|
||||
|
||||
/// Parameterizable animation track
|
||||
template <typename T> class AnimationTrack : public AbstractAnimationTrack {
|
||||
public:
|
||||
AnimationTrack(EType type, size_t nKeyframes)
|
||||
: AbstractAnimationTrack(type),
|
||||
m_times(nKeyframes), m_values(nKeyframes) { }
|
||||
|
||||
/// Return the number of keyframes
|
||||
inline size_t getSize() const { return m_times.size(); }
|
||||
|
||||
/// Set the time value of a certain keyframe
|
||||
inline void setTime(size_t idx, Float time) { m_times[idx] = time; }
|
||||
|
||||
/// Return the time value of a certain keyframe
|
||||
inline Float getTime(size_t idx) const { return m_times[idx]; }
|
||||
|
||||
/// Return the number of keyframes
|
||||
inline size_t getSize() const { return m_times.size(); }
|
||||
|
||||
protected:
|
||||
AbstractAnimationTrack(EType type, size_t nKeyframes)
|
||||
: m_type(type), m_times(nKeyframes) { }
|
||||
|
||||
protected:
|
||||
EType m_type;
|
||||
std::vector<Float> m_times;
|
||||
};
|
||||
|
||||
/// Parameterizable animation track
|
||||
template <typename T> class AnimationTrack : public AbstractAnimationTrack {
|
||||
public:
|
||||
AnimationTrack(EType type, size_t nKeyframes)
|
||||
: AbstractAnimationTrack(type, nKeyframes), m_values(nKeyframes) { }
|
||||
|
||||
/// Set the value of a certain keyframe
|
||||
inline void setValue(size_t idx, const T &value) { m_values[idx] = value; }
|
||||
|
@ -72,7 +74,6 @@ public:
|
|||
inline T lookup(Float time) const {
|
||||
}
|
||||
private:
|
||||
std::vector<Float> m_times;
|
||||
std::vector<T> m_values;
|
||||
};
|
||||
|
||||
|
|
|
@ -62,9 +62,11 @@ public:
|
|||
* Unserialize a triangle mesh - this is an alternative
|
||||
* routine, which only loads triangle data (no BSDF,
|
||||
* Sub-surface integrator, etc.) in a format that
|
||||
* will remain stable as Mitsuba evolves.
|
||||
* will remain stable as Mitsuba evolves. The files
|
||||
* can optionally contain multiple meshes -- in that case,
|
||||
* the specified index determines which one to load.
|
||||
*/
|
||||
TriMesh(Stream *stream);
|
||||
TriMesh(Stream *stream, int idx = 0);
|
||||
|
||||
/// Return the name of this mesh
|
||||
virtual std::string getName() const;
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
typedef AnimationTrack<Float> FloatTrack;
|
||||
typedef AnimationTrack<Quaternion> QuatTrack;
|
||||
typedef AnimationTrack<Vector> VectorTrack;
|
||||
typedef AnimationTrack<Point> PointTrack;
|
||||
typedef std::map<std::string, std::string> StringMap;
|
||||
typedef std::map<std::string, int> RefCountMap;
|
||||
typedef std::multimap<std::string, AbstractAnimationTrack *> AnimationMap;
|
||||
|
@ -456,11 +458,20 @@ void writeGeometry(ColladaContext &ctx, const std::string &prefixName, std::stri
|
|||
}
|
||||
|
||||
id += formatString("_%i", geomIndex);
|
||||
std::string filename = id + std::string(".serialized");
|
||||
ref<FileStream> stream = new FileStream(ctx.meshesDirectory / filename, FileStream::ETruncReadWrite);
|
||||
stream->setByteOrder(Stream::ELittleEndian);
|
||||
mesh->serialize(stream);
|
||||
stream->close();
|
||||
std::string filename;
|
||||
|
||||
if (!ctx.cvt->m_geometryFile) {
|
||||
filename = id + std::string(".serialized");
|
||||
ref<FileStream> stream = new FileStream(ctx.meshesDirectory / filename, FileStream::ETruncReadWrite);
|
||||
stream->setByteOrder(Stream::ELittleEndian);
|
||||
mesh->serialize(stream);
|
||||
stream->close();
|
||||
filename = "meshes/" + filename;
|
||||
} else {
|
||||
ctx.cvt->m_geometryDict.push_back(ctx.cvt->m_geometryFile->getPos());
|
||||
mesh->serialize(ctx.cvt->m_geometryFile);
|
||||
filename = ctx.cvt->m_geometryFileName.filename();
|
||||
}
|
||||
|
||||
std::ostringstream matrix;
|
||||
for (int i=0; i<4; ++i)
|
||||
|
@ -470,7 +481,9 @@ void writeGeometry(ColladaContext &ctx, const std::string &prefixName, std::stri
|
|||
|
||||
if (!exportShapeGroup) {
|
||||
ctx.os << "\t<shape id=\"" << id << "\" type=\"serialized\">" << endl;
|
||||
ctx.os << "\t\t<string name=\"filename\" value=\"meshes/" << filename << "\"/>" << endl;
|
||||
ctx.os << "\t\t<string name=\"filename\" value=\"" << filename << "\"/>" << endl;
|
||||
if (ctx.cvt->m_geometryFile)
|
||||
ctx.os << "\t\t<integer name=\"shapeIndex\" value=\"" << (ctx.cvt->m_geometryDict.size() - 1) << "\"/>" << endl;
|
||||
if (!transform.isIdentity()) {
|
||||
ctx.os << "\t\t<transform name=\"toWorld\">" << endl;
|
||||
ctx.os << "\t\t\t<matrix value=\"" << matrixValues.substr(0, matrixValues.length()-1) << "\"/>" << endl;
|
||||
|
@ -481,7 +494,9 @@ void writeGeometry(ColladaContext &ctx, const std::string &prefixName, std::stri
|
|||
ctx.os << "\t</shape>" << endl << endl;
|
||||
} else {
|
||||
ctx.os << "\t\t<shape type=\"serialized\">" << endl;
|
||||
ctx.os << "\t\t\t<string name=\"filename\" value=\"meshes/" << filename << "\"/>" << endl;
|
||||
ctx.os << "\t\t\t<string name=\"filename\" value=\"" << filename << "\"/>" << endl;
|
||||
if (ctx.cvt->m_geometryFile)
|
||||
ctx.os << "\t\t<integer name=\"shapeIndex\" value=\"" << (ctx.cvt->m_geometryDict.size() - 1)<< "\"/>" << endl;
|
||||
if (matID != "")
|
||||
ctx.os << "\t\t\t<ref name=\"bsdf\" id=\"" << matID << "\"/>" << endl;
|
||||
ctx.os << "\t\t</shape>" << endl << endl;
|
||||
|
@ -743,8 +758,7 @@ void loadMaterial(ColladaContext &ctx, domMaterial &mat) {
|
|||
identifier = formatString("unnamedMat_%i", unnamedCtr++);
|
||||
}
|
||||
}
|
||||
StringMap idToTexture = ctx.idToTexture;
|
||||
|
||||
|
||||
daeURI &effRef = mat.getInstance_effect()->getUrl();
|
||||
effRef.resolveElement();
|
||||
domEffect *effect = daeSafeCast<domEffect>(effRef.getElement());
|
||||
|
@ -773,16 +787,16 @@ void loadMaterial(ColladaContext &ctx, domMaterial &mat) {
|
|||
= surface->getFx_surface_init_common()->getInit_from_array();
|
||||
SAssert(initFromArray.getCount() == 1);
|
||||
std::string id = initFromArray[0]->getValue().getID();
|
||||
if (idToTexture.find(id) == idToTexture.end())
|
||||
if (ctx.idToTexture.find(id) == ctx.idToTexture.end())
|
||||
SLog(EError, "Referenced bitmap '%s' not found!", id.c_str());
|
||||
idToTexture[newParam->getSid()] = idToTexture[id];
|
||||
ctx.idToTexture[newParam->getSid()] = ctx.idToTexture[id];
|
||||
}
|
||||
|
||||
if (sampler2D) {
|
||||
std::string id = sampler2D->getSource()->getValue();
|
||||
if (idToTexture.find(id) == idToTexture.end())
|
||||
if (ctx.idToTexture.find(id) == ctx.idToTexture.end())
|
||||
SLog(EError, "Referenced surface '%s' not found!", id.c_str());
|
||||
idToTexture[newParam->getSid()] = idToTexture[id];
|
||||
ctx.idToTexture[newParam->getSid()] = ctx.idToTexture[id];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1314,7 +1328,7 @@ void loadAnimation(ColladaContext &ctx, domAnimation &anim) {
|
|||
for (size_t i=0; i<channels.getCount(); ++i) {
|
||||
domChannel *channel = channels[i];
|
||||
std::vector<std::string> target = tokenize(channel->getTarget(), "./");
|
||||
SAssertEx(target.size() == 3, "Encountered an unknown animation channel identifier!");
|
||||
SAssert(target.size() >= 2);
|
||||
|
||||
daeURI &sourceRef = channel->getSource();
|
||||
sourceRef.resolveElement();
|
||||
|
@ -1322,12 +1336,15 @@ void loadAnimation(ColladaContext &ctx, domAnimation &anim) {
|
|||
if (!sampler)
|
||||
SLog(EError, "Referenced animation sampler not found!");
|
||||
const domInputLocal_Array &inputs = sampler->getInput_array();
|
||||
FloatTrack *track = NULL;
|
||||
FloatTrack::EType trackType = FloatTrack::EInvalid;
|
||||
AbstractAnimationTrack *track = NULL;
|
||||
AbstractAnimationTrack::EType trackType = AbstractAnimationTrack::EInvalid;
|
||||
boost::to_lower(target[1]);
|
||||
boost::to_lower(target[2]);
|
||||
if (target[1] == "location") {
|
||||
if (target[2] == "x") {
|
||||
if (target.size() > 2)
|
||||
boost::to_lower(target[2]);
|
||||
if (target[1] == "location" || target[1] == "translate") {
|
||||
if (target.size() == 2) {
|
||||
trackType = PointTrack::ELocationXYZ;
|
||||
} else if (target[2] == "x") {
|
||||
trackType = FloatTrack::ELocationX;
|
||||
} else if (target[2] == "y") {
|
||||
trackType = FloatTrack::ELocationY;
|
||||
|
@ -1335,24 +1352,26 @@ void loadAnimation(ColladaContext &ctx, domAnimation &anim) {
|
|||
trackType = FloatTrack::ELocationZ;
|
||||
}
|
||||
} else if (target[1] == "scale") {
|
||||
if (target[2] == "x") {
|
||||
if (target.size() == 2) {
|
||||
trackType = VectorTrack::EScaleXYZ;
|
||||
} else if (target[2] == "x") {
|
||||
trackType = FloatTrack::EScaleX;
|
||||
} else if (target[2] == "y") {
|
||||
trackType = FloatTrack::EScaleY;
|
||||
} else if (target[3] == "z") {
|
||||
trackType = FloatTrack::EScaleZ;
|
||||
}
|
||||
} else if (target[1] == "rotationx" && target[2] == "angle") {
|
||||
} else if ((target[1] == "rotationx" || target[1] == "rotatex") && target.size() == 3 && target[2] == "angle") {
|
||||
trackType = FloatTrack::ERotationX;
|
||||
} else if (target[1] == "rotationy" && target[2] == "angle") {
|
||||
} else if ((target[1] == "rotationy" || target[1] == "rotatey") && target.size() == 3 && target[2] == "angle") {
|
||||
trackType = FloatTrack::ERotationY;
|
||||
} else if (target[1] == "rotationz" && target[2] == "angle") {
|
||||
} else if ((target[1] == "rotationz" || target[1] == "rotatez") && target.size() == 3 && target[2] == "angle") {
|
||||
trackType = FloatTrack::ERotationZ;
|
||||
}
|
||||
|
||||
if (trackType == FloatTrack::EInvalid) {
|
||||
SLog(EWarn, "Skipping unsupported animation track of type %s.%s",
|
||||
target[1].c_str(), target[2].c_str());
|
||||
target[1].c_str(), target.size() > 2 ? target[2].c_str() : "");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1369,27 +1388,44 @@ void loadAnimation(ColladaContext &ctx, domAnimation &anim) {
|
|||
domAccessor *accessor = techniqueCommon->getAccessor();
|
||||
if (!accessor)
|
||||
SLog(EError, "Data source does not have a <accessor> tag!");
|
||||
unsigned int nParams = (unsigned int) accessor->getParam_array().getCount(),
|
||||
stride = (unsigned int) accessor->getStride();
|
||||
unsigned int stride = (unsigned int) accessor->getStride();
|
||||
size_t size = (size_t) accessor->getCount();
|
||||
|
||||
if (stride != 1 || nParams != 1) {
|
||||
/// Only single-valued tracks are supported for now
|
||||
SLog(EError, "Encountered a multi-valued animation track.");
|
||||
}
|
||||
if (!track)
|
||||
track = new FloatTrack(trackType, size);
|
||||
else
|
||||
if (!track) {
|
||||
if (trackType == VectorTrack::EScaleXYZ)
|
||||
track = new VectorTrack(trackType, size);
|
||||
else if (trackType == PointTrack::ELocationXYZ)
|
||||
track = new PointTrack(trackType, size);
|
||||
else
|
||||
track = new FloatTrack(trackType, size);
|
||||
} else {
|
||||
SAssert(track->getSize() == size);
|
||||
}
|
||||
|
||||
if (semantic == "INPUT") {
|
||||
domListOfFloats &floatArray = source->getFloat_array()->getValue();
|
||||
for (size_t i=0; i<size; ++i)
|
||||
SAssert(stride == 1);
|
||||
for (size_t i=0; i<size; ++i)
|
||||
track->setTime(i, floatArray[i]);
|
||||
} else if (semantic == "OUTPUT") {
|
||||
domListOfFloats &floatArray = source->getFloat_array()->getValue();
|
||||
for (size_t i=0; i<size; ++i)
|
||||
track->setValue(i, floatArray[i]);
|
||||
if (trackType == PointTrack::ELocationXYZ) {
|
||||
SAssert(stride == 3);
|
||||
for (size_t i=0; i<size; ++i)
|
||||
((PointTrack *) track)->setValue(i,
|
||||
Point(floatArray[i*3+0], floatArray[i*3+1],
|
||||
floatArray[i*3+2]));
|
||||
} else if (trackType == PointTrack::EScaleXYZ) {
|
||||
SAssert(stride == 3);
|
||||
for (size_t i=0; i<size; ++i)
|
||||
((VectorTrack *) track)->setValue(i,
|
||||
Vector(floatArray[i*3+0], floatArray[i*3+1],
|
||||
floatArray[i*3+2]));
|
||||
} else {
|
||||
SAssert(stride == 1);
|
||||
for (size_t i=0; i<size; ++i)
|
||||
((FloatTrack *) track)->setValue(i, floatArray[i]);
|
||||
}
|
||||
} else if (semantic == "INTERPOLATION") {
|
||||
/// Ignored for now
|
||||
} else {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <xercesc/framework/LocalFileFormatTarget.hpp>
|
||||
#include <xercesc/util/XMLUni.hpp>
|
||||
#include <mitsuba/core/fresolver.h>
|
||||
#include <mitsuba/core/fstream.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -139,6 +140,13 @@ void GeometryConverter::convert(const fs::path &inputFile,
|
|||
outputFile = outputDirectory / sceneName;
|
||||
}
|
||||
|
||||
if (m_packGeometry) {
|
||||
m_geometryFileName = outputDirectory / sceneName;
|
||||
m_geometryFileName.replace_extension(".serialized");
|
||||
m_geometryFile = new FileStream(m_geometryFileName, FileStream::ETruncReadWrite);
|
||||
m_geometryFile->setByteOrder(Stream::ELittleEndian);
|
||||
}
|
||||
|
||||
if (!fs::exists(textureDirectory)) {
|
||||
SLog(EInfo, "Creating directory \"%s\" ..", textureDirectory.file_string().c_str());
|
||||
fs::create_directory(textureDirectory);
|
||||
|
@ -237,6 +245,13 @@ void GeometryConverter::convert(const fs::path &inputFile,
|
|||
ofile << os.str();
|
||||
ofile.close();
|
||||
}
|
||||
if (m_geometryFile) {
|
||||
for (size_t i=0; i<m_geometryDict.size(); ++i)
|
||||
m_geometryFile->writeUInt(m_geometryDict[i]);
|
||||
m_geometryFile->writeUInt((uint32_t) m_geometryDict.size());
|
||||
m_geometryFile->close();
|
||||
}
|
||||
|
||||
m_filename = outputFile;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
m_samplesPerPixel = 8;
|
||||
m_fov = -1;
|
||||
m_filmType = "exrfilm";
|
||||
m_packGeometry = true;
|
||||
}
|
||||
|
||||
void convert(const fs::path &inputFile,
|
||||
|
@ -42,6 +43,7 @@ public:
|
|||
inline void setMapSmallerSide(bool mapSmallerSide) { m_mapSmallerSide = mapSmallerSide; }
|
||||
inline void setResolution(int xres, int yres) { m_xres = xres; m_yres = yres; }
|
||||
inline void setSamplesPerPixel(int samplesPerPixel) { m_samplesPerPixel = samplesPerPixel; }
|
||||
inline void setPackGeometry(bool packGeometry) { m_packGeometry = packGeometry; }
|
||||
inline void setFov(Float fov) { m_fov = fov; }
|
||||
inline void setFilmType(const std::string &filmType) { m_filmType = filmType; }
|
||||
inline const fs::path &getFilename() const { return m_filename; }
|
||||
|
@ -58,4 +60,8 @@ public:
|
|||
Float m_fov;
|
||||
fs::path m_filename;
|
||||
std::string m_filmType;
|
||||
ref<FileStream> m_geometryFile;
|
||||
fs::path m_geometryFileName;
|
||||
std::vector<uint32_t> m_geometryDict;
|
||||
bool m_packGeometry;
|
||||
};
|
||||
|
|
|
@ -57,6 +57,7 @@ void help() {
|
|||
<< " -p <num> Use the specified number of samples per pixel." << endl << endl
|
||||
<< " -s Assume that colors are in sRGB space." << endl << endl
|
||||
<< " -m Map the larger image side to the full field of view" << endl << endl
|
||||
<< " -y Don't pack all geometry data into a single file" << endl << endl
|
||||
<< " -l <type> Override the type of film (e.g. 'exrfilm', 'pngfilm', ..)" << endl << endl
|
||||
<< " -r <w>x<h> Override the image resolution to e.g. 1920x1080" << endl << endl
|
||||
<< " -f <fov> Override the field of view to the given value in degrees." << endl << endl
|
||||
|
@ -72,10 +73,11 @@ int colladaMain(int argc, char **argv) {
|
|||
Float fov = -1;
|
||||
FileResolver *fileResolver = Thread::getThread()->getFileResolver();
|
||||
ELogLevel logLevel = EInfo;
|
||||
bool packGeometry = true;
|
||||
|
||||
optind = 1;
|
||||
|
||||
while ((optchar = getopt(argc, argv, "svhmr:a:p:f:l:")) != -1) {
|
||||
while ((optchar = getopt(argc, argv, "svyhmr:a:p:f:l:")) != -1) {
|
||||
switch (optchar) {
|
||||
case 'a': {
|
||||
std::vector<std::string> paths = tokenize(optarg, ";");
|
||||
|
@ -100,6 +102,9 @@ int colladaMain(int argc, char **argv) {
|
|||
case 'l':
|
||||
filmType = optarg;
|
||||
break;
|
||||
case 'y':
|
||||
packGeometry = false;
|
||||
break;
|
||||
case 'f':
|
||||
fov = (Float) strtod(optarg, &end_ptr);
|
||||
if (*end_ptr != '\0')
|
||||
|
@ -138,6 +143,7 @@ int colladaMain(int argc, char **argv) {
|
|||
converter.setMapSmallerSide(mapSmallerSide);
|
||||
converter.setSamplesPerPixel(samplesPerPixel);
|
||||
converter.setFov(fov);
|
||||
converter.setPackGeometry(packGeometry);
|
||||
converter.setFilmType(filmType);
|
||||
|
||||
const Logger *logger = Thread::getThread()->getLogger();
|
||||
|
|
|
@ -182,14 +182,24 @@ void GeometryConverter::convertOBJ(const fs::path &inputFile,
|
|||
TriMesh *mesh = static_cast<TriMesh *>(rootShape->getElement(ctr++));
|
||||
if (!mesh)
|
||||
break;
|
||||
std::string filename = mesh->getName() + std::string(".serialized");
|
||||
SLog(EInfo, "Saving \"%s\"", filename.c_str());
|
||||
ref<FileStream> stream = new FileStream(meshesDirectory / filename, FileStream::ETruncReadWrite);
|
||||
stream->setByteOrder(Stream::ELittleEndian);
|
||||
mesh->serialize(stream);
|
||||
stream->close();
|
||||
os << "\t<shape id=\"" << mesh->getName() << "\" type=\"serialized\">" << endl;
|
||||
os << "\t\t<string name=\"filename\" value=\"meshes/" << filename.c_str() << "\"/>" << endl;
|
||||
|
||||
if (!m_geometryFile) {
|
||||
std::string filename = mesh->getName() + std::string(".serialized");
|
||||
SLog(EInfo, "Saving \"%s\"", filename.c_str());
|
||||
ref<FileStream> stream = new FileStream(meshesDirectory / filename, FileStream::ETruncReadWrite);
|
||||
stream->setByteOrder(Stream::ELittleEndian);
|
||||
mesh->serialize(stream);
|
||||
stream->close();
|
||||
os << "\t\t<string name=\"filename\" value=\"meshes/" << filename.c_str() << "\"/>" << endl;
|
||||
} else {
|
||||
m_geometryDict.push_back(m_geometryFile->getPos());
|
||||
SLog(EInfo, "Saving mesh \"%s\"", mesh->getName().c_str());
|
||||
mesh->serialize(m_geometryFile);
|
||||
os << "\t\t<string name=\"filename\" value=\"" << m_geometryFileName.filename() << "\"/>" << endl;
|
||||
os << "\t\t<integername=\"shapeIndex\" value=\"" << (m_geometryDict.size()-1) << "\"/>" << endl;
|
||||
}
|
||||
|
||||
if (mesh->getBSDF() != NULL &&
|
||||
mtlList.find(mesh->getBSDF()->getName()) != mtlList.end()) {
|
||||
const std::string &matID = mesh->getBSDF()->getName();
|
||||
|
|
|
@ -151,9 +151,25 @@ static void readHelper(Stream *stream, bool fileDoublePrecision,
|
|||
}
|
||||
}
|
||||
|
||||
TriMesh::TriMesh(Stream *_stream) : Shape(Properties()), m_tangents(NULL) {
|
||||
TriMesh::TriMesh(Stream *_stream, int index)
|
||||
: Shape(Properties()), m_tangents(NULL) {
|
||||
ref<Stream> stream = _stream;
|
||||
|
||||
if (index != 0) {
|
||||
/* Determine the position of the requested substream. This
|
||||
is stored at the end of the file */
|
||||
stream->setPos(stream->getSize() - sizeof(uint32_t));
|
||||
uint32_t count = stream->readUInt();
|
||||
if (index < 0 || index > (int) count) {
|
||||
Log(EError, "Unable to unserialize mesh, "
|
||||
"shape index is out of range! (requested %i out of 0..%i)",
|
||||
index, count-1);
|
||||
}
|
||||
stream->setPos(stream->getSize() - sizeof(uint32_t) * (1+count-index));
|
||||
// Seek to the correct position
|
||||
stream->setPos(stream->readUInt());
|
||||
}
|
||||
|
||||
if (stream->getByteOrder() != Stream::ELittleEndian)
|
||||
Log(EError, "Tried to unserialize a shape from a stream, "
|
||||
"which was not previously set to little endian byte order!");
|
||||
|
|
|
@ -35,13 +35,16 @@ public:
|
|||
/* Object-space -> World-space transformation */
|
||||
Transform objectToWorld = props.getTransform("toWorld", Transform());
|
||||
|
||||
/// When the file contains multiple meshes, this index specifies which one to load
|
||||
int shapeIndex = props.getInteger("shapeIndex", 0);
|
||||
|
||||
m_name = filePath.stem();
|
||||
|
||||
/* Load the geometry */
|
||||
Log(EInfo, "Loading geometry from \"%s\" ..", filePath.leaf().c_str());
|
||||
ref<FileStream> stream = new FileStream(filePath, FileStream::EReadOnly);
|
||||
stream->setByteOrder(Stream::ELittleEndian);
|
||||
ref<TriMesh> mesh = new TriMesh(stream);
|
||||
ref<TriMesh> mesh = new TriMesh(stream, shapeIndex);
|
||||
m_triangleCount = mesh->getTriangleCount();
|
||||
m_vertexCount = mesh->getVertexCount();
|
||||
|
||||
|
|
|
@ -184,6 +184,21 @@ public:
|
|||
*flData++ = 1.0f;
|
||||
}
|
||||
}
|
||||
} else if (bitmap->getBitsPerPixel() == 1) {
|
||||
int pos = 0;
|
||||
for (int y=0; y<bitmap->getHeight(); ++y) {
|
||||
for (int x=0; x<bitmap->getWidth(); ++x) {
|
||||
int entry = pos / 8;
|
||||
int bit = pos % 8;
|
||||
int value = (data[entry] & (1 << bit)) ? 255 : 0;
|
||||
float col = tbl[value];
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = col;
|
||||
*flData++ = 1.0f;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log(EError, "%i bpp images are currently not supported!", bitmap->getBitsPerPixel());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue