VS 2012에서 FBX SDK 2013.3을 써서 씬 읽어들이려고 별의 별 삽질을 다 해봐도 FbxMesh::mPolygons가 쓰레기값인 상태를 해결할 수가 없었다. 2013.x는 VS2010을 지원하고, 구글링해보면 VS2012갖고 FBX loader를 만들었던 사례가 보여서 계속 시도하고 있었는데,

모든것이 삽질이었다.

플랫폼 툴셋을 v100으로 맞추면 정상적으로 동작한다. 결론적으로 SDK 2013.x는 VS2012환경에서 사용할 수 없다.

현재 beta상태인 2014.x가 VS2012 지원을 포함하고 있다는 소문을 듣고 오토데스크에 메일 보내서 베타 신청까지만 해뒀다.

#include <iostream>
#include <memory>
#include <list>
#include <algorithm>

using namespace std;

struct Foo
{
	Foo(int number)
		: number(number)
	{ cout << "ctor(" << number << ")"<< endl; }
	~Foo()
	{ cout << "dtor(" << number << ")"<< endl; }

	int number;
};

void main()
{
	list<shared_ptr<Foo>> originallist;;
	list<weak_ptr<Foo>> list;

	//원본이 존재하지 않는 weak_ptr은 dangle이므로 원본을 유지하는 리스트를 작성.
	for (int i = 0; i < 10; i++)
		originallist.push_back( make_shared<Foo>(i) );

	for (auto& itr : originallist)
		list.push_back( itr );

	weak_ptr<Foo> temp;
	const int someIndex = 6;

	for (auto itr : list)
	{
		//이 루프 내에서만 shaerd_ptr로 사용.
		//방어적 코딩을 할 때는 lock의 결과가 nullptr이 아닌 것을 확인한 후에 사용해야 안전하다.
		auto item (itr.lock());
		cout << item->number << endl;

		if (item->number == someIndex)
			temp = itr;
	}

	//weak_ptr은 operator== 을 구현하지 않는다. 따라서 find를 사용할 수 없음
	//find가 필요할 경우 find_if와 shared_ptr을 비교하는 람다를 사용해야 한다.
	//D라면 lambda에서도 타입 추론이 되니까 auto 넣으면 끝인데
	//C++은 lambda안에서는 auto 사용 불가능이라 유감.
	auto selector = [&temp](weak_ptr<Foo> item){ return item.lock() == temp.lock();};

	auto itr (std::find_if(list.begin(), list.end(), selector));

	auto foundItem (itr->lock());

	cout << "found item : " << foundItem->number << endl;
}

todo: raw pointer와 weak_ptr을 컨테이너와 함께 사용할 때의 오버헤드를 벤치마크 해보거나 자료를 찾아볼 필요가 있겠다. weak_ptr은 컨테이너에 넣어서 사용하기에는 너무 불편한 점이 많다. 컨테이너와 사용할 경우에는 shared_ptr을 사용하거나, 순환참조가 있을 경우에는 raw pointer를 사용하는 것이 나을 듯.

#include <iostream>
#include <memory>
#include <vector>

using namespace std;

class Foo
{
public:
	Foo(int number)
		: number(number)
	{
		cout << "ctor(" << number << ")"<< endl;
	}
	~Foo()
	{
		cout << "dtor(" << number << ")"<< endl;
	}

	int number;
};

void main()
{
	vector<shared_ptr<Foo>> list;

	for (int i = 0; i < 10; i++)
	{
		list.push_back( make_shared<Foo>(i) );
	}


	for (auto itr : list )
	{
		cout << itr->number << endl;
	}

	shared_ptr<Foo> temp( list[0] );

	list.clear();

	cout<< "list cleared"<< endl;

}

/*
result:
ctor(0)
ctor(1)
ctor(2)
ctor(3)
ctor(4)
ctor(5)
ctor(6)
ctor(7)
ctor(8)
ctor(9)
0
1
2
3
4
5
6
7
8
9
dtor(1)
dtor(2)
dtor(3)
dtor(4)
dtor(5)
dtor(6)
dtor(7)
dtor(8)
dtor(9)
list cleared
dtor(0)
*/

range for가 지원되니까 정말 좋다.