レイトレーサはほぼ完成。実行速度は一気に落ちて300ms@Releaseともはやどこがリアルタイムだか分からない結果に。オブジェクト数が少ないと100msを切れるのだが、屈折・透過・鏡面反射をするオブジェクトが複数あれば計算量は指数的に増えるわけで…。とはいえそろそろフォトンマッピングが見えてきた、かな?
今日からはメタセコイアデータ(MQOフォーマット)を読み込んでレイトレーシングで描画するビューアの作成に取り掛かっている。さて、メタセコのデータを読むにあたって、テキストファイルを解釈しなければならない。そんな時にstd::stringクラスを任意のデリミタ(分割子)で分割できると便利なので、早速作ってみた。こちらのサイトが非常に参考になった。
#include <iostream>
#include <vector>
#include <string>
typedef std::string String;
typedef std::vector<String> StringList;
/**
* 文字列を分割してコンテナに格納する
* @param dest 分割後の文字列格納先へのポインタ
* @param src 分割したい文字列への参照
* @param delim デリミタ文字列への参照
* @return 分割後の文字列格納先へのポインタ
*/
StringList *SpritString(
StringList *dest,
const String &src,
const String &delim
)
{
String::size_type start = 0;//デリミタを検索するインデクス番号
while(true){
//デリミタが現れる最初のインデクスを求める
String::size_type end = src.find(delim, start);
//デリミタが見つかった場合
if(end != String::npos){
dest->push_back(src.substr(start, end - start));
}
//デリミタが見つからなかった場合
else{
//文末までを格納して返す
dest->push_back(src.substr(start, src.length() - start));
break;
}
//次の開始地点へ移動
start = end + delim.length();
}
return dest;
}
/**
* 呼び出し側
*/
int main(){
using namespace std;
String src("hoge piyo fuga");//区切りたい文字列
String delim(" ");//デリミタ(区切り文字)
StringList out;//区切られた文字が配列となって帰ってくる
SpritString(&out, src, delim);//空白文字で区切る
//出力
for(String::size_type i=0; i<out.size(); ++i){
cout << out[i] << endl;
}
/* 出力結果---------------------------
> hoge
> piyo
> fuga
*/
return 0;
}
参考先のサイトでは関数内部で作成したリストオブジェクトをそのまま返していたので、軽くする目的でポインタ経由での受け渡しにしてみた。そもそも軽くしたいならstd::stringなんか使うなって話だが…。便利なんだもん。デリミタ自体もベクタオブジェクトに突っ込んで、複数のデリミタに対応するとかいろいろ出来そう。
MQOローダ自体は以前も作ったのだが、設計が気に食わなかったので最初から作り直している。その際に『ゲームプログラマになる前に覚えておきたい技術(通称:セガ本)』の「XMLモドキを読む」という項が大変参考になった。MQOファイル自体はXML形式ではないので若干の改造が必要になるが、基本となる考え方はセガ本からまるまるパクッている。明日には完成させたい。
0 件のコメント:
コメントを投稿