FKまで実装完了
ひとまずFKの実装まで完了。
踏んだ地雷について。
core::quaternion::getMatrixがおかしい
今まで見たことのない微妙な歪み具合に2時間くらいはまる。結局Irrlichtの方に問題があったみたい。quaternionから回転行列を得るところで変な値が返ってくるようだ。
誰も使ってないのかしら。
代替コード
static core::matrix4 getMatrix(const core::quaternion &rot) { float xx=rot.X*rot.X; float yy=rot.Y*rot.Y; float zz=rot.Z*rot.Z; float xy=rot.X*rot.Y; float yz=rot.Y*rot.Z; float zx=rot.Z*rot.X; float wx=rot.W*rot.X; float wy=rot.W*rot.Y; float wz=rot.W*rot.Z; core::matrix4 m(core::matrix4::EM4CONST_IDENTITY); m[0]=1-2*(yy+zz); m[1]=2*(xy+wz); m[2]=2*(zx-wy); m[4]=2*(xy-wz); m[5]=1-2*(xx+zz); m[6]=2*(yz+wx); m[8]=2*(zx+wy); m[9]=2*(yz-wx); m[10]=1-2*(xx+yy); return m; }
core::vector3df::getInterpolatedがおかしい
境界付近でワープする。
これはすぐわかったが誰も使ってないのかしら。
代替コード。
static core::vector3df getInterpolated( const core::vector3df &s, const core::vector3df &e, f32 factor) { return core::vector3df( s.X+(e.X-s.X)*factor, s.Y+(e.Y-s.Y)*factor, s.Z+(e.Z-s.Z)*factor ); }
1フレーム目で固まる
IMeshBuffer::setDirty(EBT_VERTEX)
を使わないとキャッシュされるみたいだ。
(SSharedMeshBufferをコンパイル通るようにして使用)
新しい地雷をいくつか踏んで除去したがまぁ順調といったところか。ただ、2コアなのにCPU負荷が両方最大になってやたら重くなる。中でスレッドでも使ってるのだろうか。まだ、単純なソフトウェアスキニングだけなのでそんなに重くならないと思うのだが・・・。さらにOpenGLのバックエンドの方がDirectXのバックエンドよりも重い。あとで、GLSLを使いたいのでこれは困る。頂点配列をキャッシュしているみたいだからその界隈が重いような気がするな。要調査。
irrlichtの描画
CSceneManager::drawAll()内の"// render default objects"で始まるブロックの中
for (i=0; i<SolidNodeList.size(); ++i) SolidNodeList[i].Node->render();
ISceneNode->Renderを呼び出す。
その中で
video::IVideoDriver *driver; scene::IMeshBuffer *mb; driver->drawMeshBuffer(mb);
と呼ばれる。
で、drawMeshBufferでハードウェアバッファに関する処理をしている様子。
毎フレームでハードウェアバッファの読み書きをしているのが負担になっていると思われる。
//! Draws a mesh buffer void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) { if (!mb) return; //IVertexBuffer and IIndexBuffer later SHWBufferLink *HWBuffer=getBufferLink(mb); if (HWBuffer) drawHardwareBuffer(HWBuffer); else drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); }
OpenGLでは
COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::IMeshBuffer* mb)
でvboを作っていた。
このvboを作成しないようににするには以下のようにする。
meshBuffer->setHardwareMappingHint(EHM_NEVER);
これで使うコアがひとつになって速度が普通になった。
ドライバがスレッド使っていたのかもしれない。
IMeshBuffer::setDirty(EBT_VERTEX)
を頻繁に呼び出す場合は注意が必要と。