私は現在、パス トレーサーの基本フレームワークに取り組んでいます。シンプルなバイナリ モデル ローダー (読み取りと書き込み) を作成しようとしていますが、ファイルの読み取りで問題が発生しました。もう少しコンテキストを与えるには:
私のデータの書き込みは順調に進んでいるようです。つまり、例外はスローされず、ファイルサイズも問題ないようです。データの読み取りを開始すると、(すべての頂点位置といくつかの法線を読み取った後) データが破損するまで、すべて問題ないように見えます。デバッグすると、すべての数値は正しいのですが、ある時点で正しい float 値ではなく #DEN が返されることは明らかです。同じことがある時点ですべてのメッシュで発生するため、UV や三角形などを読み取るときに発生する可能性があります。
(画像 #DEN at 54th Normal (3rd float) ...評判が足りない)
すべての法線 (1 つのサブメッシュ) を一度に読み取りました。ifstream を見ると、ファイルの先頭にリセットされます。三角形のインデックス (新しい stream.read()) の読み取りを開始すると、badbit が設定されます。
Visual Studio 2010 Ultimate を使用しており、Windows 7 Professional x64 で実行しています。私はCとC++を使用しています。
重要なコードのみを表示しようとします。
if(meshHeader.numberOfNormals > 0)
{
Normal* _normals = Read<Normal>(meshHeader.numberOfNormals);
if(_normals)
{
// Copy from array to vector
_normalsVec = new vector<Normal>(_normals, _normals + meshHeader.numberOfNormals);
// Cleanup
delete[] _normals;
}
else
{
// Cleanup
delete[] _normals;
throw runtime_error("Failed reading vertex normals");
}
}
読み取り方法:
template <typename T>
T* BinaryModelIO::Read(unsigned int _size)
{
T* _data = new T[_size];
unsigned int _numberOfBytes = Read(sizeof(T) * _size, static_cast<void*>(_data));
if(_numberOfBytes != (sizeof(T) * _size))
{
delete[] _data;
_data = 0;
}
return _data;
}
( static_cast(_data) が原因ではありません) 続きを読む:
unsigned int BinaryModelIO::Read(unsigned int _numberOfBytes, void *_buffer)
{
if(isWriter)
return 0;
// no fail bit set?
if(!readStream->fail())
{
try
{
readStream->read((char*)_buffer, _numberOfBytes);
}
catch(exception &e)
{
cerr << e.what() << endl;
//return 0;
}
return _numberOfBytes;
}
else
{
if(readStream->badbit)
cerr << "badbit" << endl;
else if(readStream->eofbit)
cerr << "eofbit" << endl;
return 0;
}
}
法線の読み取りは期待どおりに行われますが、ある程度のフロート (法線) の後ではうまくいきません。for ループで法線の配列全体を読み取ってから、すべての要素をベクターにコピーしようとしましたが、これは問題ではありませんでした。Triangle データを読み取るとき (同様の方法で実行)、badbit が設定されます (または、Triangle が読み取られる前のどこかに)。下の画像では、三角形を読み取りながらデバッグしていて、badbit が出力されています。
(印刷物を示す画像...評判が足りない)
読み取り/書き込みしようとしているデータ構造には仮想関数が含まれておらず、すべてフロートで構成されています (3 つの unsigned int を持つ三角形を除く)。ポイント (3 つの float)、UV (2 つの float)、Normal (3 つの float)、Triangle (3 つの unsigned int)。
編集:これが法線の定義です
class Normal
{
public:
// Vector Public Methods
Normal(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) : x(_x), y(_y), z(_z) { }
explicit Normal(const Vector3& _vector);
explicit Normal(const Point& _point);
// Overloaded Operators
Normal operator+(const Normal& _norm) const
{
return Normal(x + _norm.x, y + _norm.y, z + _norm.z);
}
Normal& operator+=(const Normal& _norm)
{
x += _norm.x;
y += _norm.y;
z += _norm.z;
return *this;
}
Normal operator-(const Normal& _norm) const
{
return Normal(x - _norm.x, y - _norm.y, z - _norm.z);
}
Normal& operator-=(const Normal& _norm)
{
x -= _norm.x;
y -= _norm.y;
z -= _norm.z;
return *this;
}
bool operator==(const Normal& _norm) const
{
return x == _norm.x && y == _norm.y && z == _norm.z;
}
bool operator!=(const Normal& _norm) const
{
return x != _norm.x || y != _norm.y || z == _norm.z;
}
Normal operator*(float _f) const
{
return Normal(_f * x, _f * y, _f * z);
}
Normal &operator*=(float _f)
{
x *= _f;
y *= _f;
z *= _f;
return *this;
}
Normal operator/(float _f) const
{
// One division, 3 multiplications ^^
float _inverse = 1.f / _f;
return Normal(x * _inverse, y * _inverse, z * _inverse);
}
Normal &operator/=(float _f)
{
float _inverse = 1.f / _f;
x *= _inverse;
y *= _inverse;
z *= _inverse;
return *this;
}
Normal operator-() const
{
return Normal(-x, -y, -z);
}
float operator[](int _i) const
{
// Return x, y or z
return (&x)[_i];
}
float &operator[](int _i)
{
return (&x)[_i];
}
float LengthSquared() const
{
return x * x + y * y + z * z;
}
float Length() const
{
return sqrtf(LengthSquared());
}
// Public Variables
float x, y, z;
}; // 12 Byte
edit2: ファイルのオープン (Loader オブジェクトの作成および破棄時に実行)
bool AbstractStream::OpenFile()
{
bool _return = false;
// We should open file to write or to read
if(isWriter)
{
// Check if the file is already open
if(!writeStream->is_open())
writeStream->open(fileName, ios::in | ios::binary);
if(!writeStream->fail())
_return = true; // File could be opened
}
else
{
// Check if the file is already open
if(!readStream->is_open())
readStream->open(fileName, ios::in | ios::binary);
if(!readStream->fail())
_return = true; // File could be opened
}
return _return; // File could be opened
}
これがスタックオーバーフローに関する私の最初の質問であるため、何かを忘れた場合は教えてください。
私はしばらくこの問題を回避したので、誰かが私を助けてくれることを本当に願っています(レンダラーの他の部分に取り組んでいます)。
前もって感謝します!