//----------------------------------------------------------------------------
void GeoObjFactory::UpdateCtrlColor1(Movable *mov, Float4 color)
{
	PX2::Node *node = DynamicCast<Node>(mov);

	if (!node)
		return;

	for (int i = 0; i < node->GetNumChildren(); i++)
	{
		PX2::Movable *child = node->GetChild(i);
		PX2::TriMesh *mesh = DynamicCast<TriMesh>(child);
		if (mesh)
		{
			VertexBuffer *vBuffer = mesh->GetVertexBuffer();

			VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC);
			VertexBufferAccessor vba(vf, vBuffer);
			for (int i = 0; i < vBuffer->GetNumElements(); i++)
			{
				vba.Color<Float4>(0, i) = color;
			}

			Renderer::UpdateAll(vBuffer);
		}

	}
}
//----------------------------------------------------------------------------
void GeoObjFactory::UpdateCtrlColor(PX2::Renderer *renderer,
	PX2::Movable *mov, Float4 color)
{
	PX2::Node *node = DynamicCast<Node>(mov);

	if (!node)
		return;

	for (int i = 0; i < node->GetNumChildren(); i++)
	{
		PX2::Movable *child = node->GetChild(i);
		PX2::Polysegment *poly = DynamicCast<Polysegment>(child);
		if (poly)
		{
			VertexBuffer *vBuffer = poly->GetVertexBuffer();

			VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC);
			VertexBufferAccessor vba(vf, vBuffer);
			for (int i = 0; i < vBuffer->GetNumElements(); i++)
			{
				vba.Color<Float4>(0, i) = color;
			}

			renderer->Update(vBuffer);
		}

	}
}
Beispiel #3
0
//----------------------------------------------------------------------------
void EditMap::AddModelActor (PX2::Movable *mov, PX2::APoint pos)
{
	if (!mov)
		return;

	PX2::Node *node = new0 PX2::Node();
	node->AttachChild(mov);
	node->SetName(mov->GetName()+"Par");

	PX2::Actor *actor = new0 Actor();
	actor->SetName("ModelActor");
	actor->SetMovable(node);
	actor->SetPosition(pos);
	actor->ComeInToEventWorld();

	AddActor(actor);
}
//----------------------------------------------------------------------------
PX2::Node *SceneBuilder::BuildNode(INode *maxNode, PX2::Node *relatParent)
{
	PX2::Node *child = new0 PX2::Node;
	child->SetName(maxNode->GetName());
	child->LocalTransform = GetLocalTransform(maxNode, mTimeStart);

	relatParent->AttachChild(child);

	TSTR strUserData;
	maxNode->GetUserPropBuffer(strUserData);
	if (strstr(strUserData, "a"))
	{
		int anchorID = 0;
		maxNode->GetUserPropInt("a", anchorID);

		child->SetAnchorID(anchorID);
	}

	return child;
}
Beispiel #5
0
//----------------------------------------------------------------------------
void EditMap::AddModelActor (PX2::Movable *mov, PX2::APoint pos)
{
	if (!mov)
		return;

	PX2::Node *node = new0 PX2::Node();
	node->AttachChild(mov);
	node->SetName(mov->GetName()+"Par");

	PX2::Actor *actor = new0 Actor();
	actor->SetName(mov->GetName());
	actor->SetMovable(node);
	actor->SetPosition(pos);
	actor->ComeInToEventWorld();
	AddActor(actor);

	Event *event = 0;
	event = EditorEventSpace::CreateEventX(EditorEventSpace::AddActor);
	event->SetData<Actor*>(actor);
	EventWorld::GetSingleton().BroadcastingLocalEvent(event);
}
//----------------------------------------------------------------------------
PX2::Node *GeoObjFactory::CreateScaleCtrl_O()
{
	// node
	PX2::Node *node = new0 Node;
	node->LocalTransform.SetUniformScale(2.0f);
	node->SetName("Scale");

	VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC);
	StandardMesh stdMesh(vf);
	VertexBuffer *vBufferTemp = 0;
	VertexBufferAccessor vbaTemp;

	// x
	PX2::Node *nodeX = new0 Node;
	nodeX->SetName("Scale_X");

	VertexBuffer *vBufferX = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaX(vf, vBufferX);

	vbaX.Position<Float3>(0) = Float3(0.25f, 0.0f, 0.0f);
	vbaX.Position<Float3>(1) = Float3(1.125f, 0.0f, 0.0f);
	vbaX.Color<Float4>(0, 0) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	vbaX.Color<Float4>(0, 1) = Float4(1.0f, 0.0f, 0.0f, 1.0f);

	vbaX.Position<Float3>(2) = Float3(0.5f, 0.0f, 0.0f);
	vbaX.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f);
	vbaX.Color<Float4>(0, 2) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	vbaX.Color<Float4>(0, 3) = Float4(0.0f, 1.0f, 0.0f, 1.0f);

	vbaX.Position<Float3>(4) = Float3(0.5f, 0.0f, 0.0f);
	vbaX.Position<Float3>(5) = Float3(0.5f, 0.0f, 0.5f);
	vbaX.Color<Float4>(0, 4) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	vbaX.Color<Float4>(0, 5) = Float4(0.0f, 0.0f, 1.0f, 1.0f);

	Polysegment *polysegmentX = new0 PX2::Polysegment(vf, vBufferX,
		false);
	polysegmentX->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeX->AttachChild(polysegmentX);

	TriMesh *meshX = stdMesh.Box(0.06f, 0.06f, 0.06f);
	meshX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshX->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshX->LocalTransform.SetTranslate(APoint(1.125f, 0.0f, 0.0f));
	vBufferTemp = meshX->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	}
	nodeX->AttachChild(meshX);

	// y
	PX2::Node *nodeY = new0 PX2::Node;
	nodeX->SetName("Scale_Y");

	VertexBuffer *vBufferY = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaY(vf, vBufferY);

	vbaY.Position<Float3>(0) = Float3(0.0f, 0.25f, 0.0f);
	vbaY.Position<Float3>(1) = Float3(0.0f, 1.125f, 0.0f);
	vbaY.Color<Float4>(0, 0) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	vbaY.Color<Float4>(0, 1) = Float4(0.0f, 1.0f, 0.0f, 1.0f);

	vbaY.Position<Float3>(2) = Float3(0.0f, 0.5f, 0.0f);
	vbaY.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f);
	vbaY.Color<Float4>(0, 2) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	vbaY.Color<Float4>(0, 3) = Float4(1.0f, 0.0f, 0.0f, 1.0f);

	vbaY.Position<Float3>(4) = Float3(0.0f, 0.5f, 0.0f);
	vbaY.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f);
	vbaY.Color<Float4>(0, 4) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	vbaY.Color<Float4>(0, 5) = Float4(0.0f, 0.0f, 1.0f, 1.0f);

	Polysegment *polysegmentY = new0 PX2::Polysegment(vf, vBufferY,
		false);
	polysegmentY->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeY->AttachChild(polysegmentY);

	TriMesh *meshY = stdMesh.Box(0.06f, 0.06f, 0.06f);
	meshY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshY->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshY->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f));
	vBufferTemp = meshY->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	}
	nodeY->AttachChild(meshY);

	// z
	PX2::Node *nodeZ = new0 PX2::Node();
	nodeX->SetName("Scale_Z");

	VertexBuffer *vBufferZ = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaZ(vf, vBufferZ);

	vbaZ.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.25f);
	vbaZ.Position<Float3>(1) = Float3(0.0f, 0.0f, 1.125f);
	vbaZ.Color<Float4>(0, 0) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	vbaZ.Color<Float4>(0, 1) = Float4(0.0f, 0.0f, 1.0f, 1.0f);

	vbaZ.Position<Float3>(2) = Float3(0.0f, 0.0f, 0.5f);
	vbaZ.Position<Float3>(3) = Float3(0.5f, 0.0f, 0.5f);
	vbaZ.Color<Float4>(0, 2) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	vbaZ.Color<Float4>(0, 3) = Float4(1.0f, 0.0f, 0.0f, 1.0f);

	vbaZ.Position<Float3>(4) = Float3(0.0f, 0.0f, 0.5f);
	vbaZ.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f);
	vbaZ.Color<Float4>(0, 4) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	vbaZ.Color<Float4>(0, 5) = Float4(0.0f, 1.0f, 0.0f, 1.0f);

	Polysegment *polysegmentZ = new0 PX2::Polysegment(vf, vBufferZ,
		false);
	polysegmentZ->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeZ->AttachChild(polysegmentZ);

	TriMesh *meshZ = stdMesh.Box(0.06f, 0.06f, 0.06f);
	meshZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshZ->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshZ->LocalTransform.SetTranslate(APoint(.0f, 0.0f, 1.125f));
	vBufferTemp = meshZ->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	}
	nodeZ->AttachChild(meshZ);

	// XYZ
	node->AttachChild(nodeX);
	node->AttachChild(nodeY);
	node->AttachChild(nodeZ);

	return node;
}
//----------------------------------------------------------------------------
PX2::Node *GeoObjFactory::CreateRolateCtrl_O()
{
	// node
	PX2::Node *node = new0 Node;
	node->LocalTransform.SetUniformScale(2.0f);
	node->SetName("Rolate");

	VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC);
	StandardMesh stdMesh(vf);
	VertexBuffer *vBufferTemp = 0;
	VertexBufferAccessor vbaTemp;

	// x
	PX2::Node *nodeX = new0 Node;
	nodeX->SetName("Rolate_X");

	TriMesh *meshX = stdMesh.Torus(40, 10, 1.0f, 0.04f);;
	meshX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshX->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshX->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_Y,
		-Mathf::HALF_PI));
	vBufferTemp = meshX->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	}
	nodeX->AttachChild(meshX);

	// y
	PX2::Node *nodeY = new0 PX2::Node;
	nodeX->SetName("Rolate_Y");

	TriMesh *meshY = stdMesh.Torus(40, 10, 1.0f, 0.04f);;
	meshY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshY->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshY->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X,
		Mathf::HALF_PI));
	vBufferTemp = meshY->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	}
	nodeY->AttachChild(meshY);

	// z
	PX2::Node *nodeZ = new0 PX2::Node();
	nodeX->SetName("Rolate_Z");

	TriMesh *meshZ = stdMesh.Torus(40, 10, 1.0f, 0.04f);;
	meshZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshZ->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshZ->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X,
		Mathf::PI));
	vBufferTemp = meshZ->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	}
	nodeZ->AttachChild(meshZ);

	// XYZ
	node->AttachChild(nodeX);
	node->AttachChild(nodeY);
	node->AttachChild(nodeZ);

	return node;
}
//----------------------------------------------------------------------------
PX2::Node *GeoObjFactory::CreateTranslateCtrl_O()
{
	// node
	PX2::Node *node = new0 Node;
	node->LocalTransform.SetUniformScale(2.0f);
	node->SetName("Translate");

	VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC);
	StandardMesh stdMesh(vf);
	VertexBuffer *vBufferTemp = 0;
	VertexBufferAccessor vbaTemp;

	// x
	PX2::Node *nodeX = new0 Node;
	nodeX->SetName("Translate_X");

	VertexBuffer *vBufferX = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaX(vf, vBufferX);

	vbaX.Position<Float3>(0) = Float3(0.25f, 0.0f, 0.0f);
	vbaX.Position<Float3>(1) = Float3(1.125f, 0.0f, 0.0f);
	vbaX.Color<Float4>(0, 0) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	vbaX.Color<Float4>(0, 1) = Float4(1.0f, 0.0f, 0.0f, 1.0f);

	vbaX.Position<Float3>(2) = Float3(0.5f, 0.0f, 0.0f);
	vbaX.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f);
	vbaX.Color<Float4>(0, 2) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	vbaX.Color<Float4>(0, 3) = Float4(0.0f, 1.0f, 0.0f, 1.0f);

	vbaX.Position<Float3>(4) = Float3(0.5f, 0.0f, 0.0f);
	vbaX.Position<Float3>(5) = Float3(0.5f, 0.0f, 0.5f);
	vbaX.Color<Float4>(0, 4) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	vbaX.Color<Float4>(0, 5) = Float4(0.0f, 0.0f, 1.0f, 1.0f);

	Polysegment *polysegmentX = new0 PX2::Polysegment(vf, vBufferX,
		false);
	polysegmentX->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeX->AttachChild(polysegmentX);

	TriMesh *meshX = stdMesh.Disk(3, 20, 0.1f);
	meshX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshX->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshX->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_Y,
		-Mathf::HALF_PI));
	meshX->LocalTransform.SetTranslate(APoint(1.125f, 0.0f, 0.0f));
	vBufferTemp = meshX->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	}
	nodeX->AttachChild(meshX);

	TriFan *fanX = stdMesh.Cone(20, 0.1f, 0.45f);
	fanX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//fanX->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	fanX->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_Y,
		Mathf::HALF_PI));
	fanX->LocalTransform.SetTranslate(APoint(1.125f, 0.0f, 0.0f));
	vBufferTemp = fanX->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	}
	nodeX->AttachChild(fanX);

	// y
	PX2::Node *nodeY = new0 PX2::Node;
	nodeX->SetName("Translate_Y");

	VertexBuffer *vBufferY = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaY(vf, vBufferY);

	vbaY.Position<Float3>(0) = Float3(0.0f, 0.25f, 0.0f);
	vbaY.Position<Float3>(1) = Float3(0.0f, 1.125f, 0.0f);
	vbaY.Color<Float4>(0, 0) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	vbaY.Color<Float4>(0, 1) = Float4(0.0f, 1.0f, 0.0f, 1.0f);

	vbaY.Position<Float3>(2) = Float3(0.0f, 0.5f, 0.0f);
	vbaY.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f);
	vbaY.Color<Float4>(0, 2) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	vbaY.Color<Float4>(0, 3) = Float4(1.0f, 0.0f, 0.0f, 1.0f);

	vbaY.Position<Float3>(4) = Float3(0.0f, 0.5f, 0.0f);
	vbaY.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f);
	vbaY.Color<Float4>(0, 4) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	vbaY.Color<Float4>(0, 5) = Float4(0.0f, 0.0f, 1.0f, 1.0f);

	Polysegment *polysegmentY = new0 PX2::Polysegment(vf, vBufferY,
		false);
	polysegmentY->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeY->AttachChild(polysegmentY);

	TriMesh *meshY = stdMesh.Disk(3, 20, 0.1f);
	meshY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshY->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshY->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X,
		Mathf::HALF_PI));
	meshY->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f));
	vBufferTemp = meshY->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	}
	nodeY->AttachChild(meshY);

	TriFan *fanY = stdMesh.Cone(20, 0.1f, 0.45f);
	fanY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//fanY->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	fanY->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X,
		-Mathf::HALF_PI));
	fanY->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f));
	vBufferTemp = fanY->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	}
	nodeY->AttachChild(fanY);

	// z
	PX2::Node *nodeZ = new0 PX2::Node();
	nodeX->SetName("Translate_Z");

	VertexBuffer *vBufferZ = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaZ(vf, vBufferZ);

	vbaZ.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.25f);
	vbaZ.Position<Float3>(1) = Float3(0.0f, 0.0f, 1.125f);
	vbaZ.Color<Float4>(0, 0) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	vbaZ.Color<Float4>(0, 1) = Float4(0.0f, 0.0f, 1.0f, 1.0f);

	vbaZ.Position<Float3>(2) = Float3(0.0f, 0.0f, 0.5f);
	vbaZ.Position<Float3>(3) = Float3(0.5f, 0.0f, 0.5f);
	vbaZ.Color<Float4>(0, 2) = Float4(1.0f, 0.0f, 0.0f, 1.0f);
	vbaZ.Color<Float4>(0, 3) = Float4(1.0f, 0.0f, 0.0f, 1.0f);

	vbaZ.Position<Float3>(4) = Float3(0.0f, 0.0f, 0.5f);
	vbaZ.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f);
	vbaZ.Color<Float4>(0, 4) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	vbaZ.Color<Float4>(0, 5) = Float4(0.0f, 1.0f, 0.0f, 1.0f);

	Polysegment *polysegmentZ = new0 PX2::Polysegment(vf, vBufferZ,
		false);
	polysegmentZ->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeZ->AttachChild(polysegmentZ);

	TriMesh *meshZ = stdMesh.Disk(3, 20, 0.1f);
	meshZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//meshZ->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	meshZ->LocalTransform.SetTranslate(APoint(.0f, 0.0f, 1.125f));
	meshZ->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X,
		Mathf::PI));
	vBufferTemp = meshZ->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	}
	nodeZ->AttachChild(meshZ);

	TriFan *fanZ = stdMesh.Cone(20, 0.1f, 0.45f);
	fanZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	//fanZ->GetMaterialInstance()->GetPass(0)->GetWireProperty()->Enabled = true;
	fanZ->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, 1.125f));
	vBufferTemp = fanZ->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 0.0f, 1.0f, 1.0f);
	}
	nodeZ->AttachChild(fanZ);

	// xy
	PX2::Node *nodeXY = new0 Node;
	nodeXY->SetName("Translate_XY");
	TriMesh *meshXY = stdMesh.Rectangle(2, 2, 0.25f, 0.25f);
	meshXY->LocalTransform.SetTranslate(APoint(0.25f, 0.25f, 0.0f));
	VertexColor4Material *matXY = new0 VertexColor4Material();
	matXY->GetAlphaProperty(0, 0)->BlendEnabled = true;
	matXY->GetCullProperty(0, 0)->Enabled = false;
	meshXY->SetMaterialInstance(matXY->CreateInstance());
	vBufferTemp = meshXY->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 1.0f, 0.0f, 0.0f);
	}
	nodeXY->AttachChild(meshXY);

	// yz
	PX2::Node *nodeYZ = new0 Node;
	nodeYZ->SetName("Translate_YZ");
	TriMesh *meshYZ = stdMesh.Rectangle(2, 2, 0.25f, 0.25f);
	meshYZ->LocalTransform.SetTranslate(APoint(0.25f, 0.25f, 0.0f));
	meshYZ->LocalTransform.SetRotate(Matrix3f().MakeEulerXYZ(0.0f, -Mathf::HALF_PI, 0.0f));
	VertexColor4Material *matYZ = new0 VertexColor4Material();
	matYZ->GetAlphaProperty(0, 0)->BlendEnabled = true;
	matYZ->GetCullProperty(0, 0)->Enabled = false;
	meshYZ->SetMaterialInstance(matYZ->CreateInstance());
	vBufferTemp = meshYZ->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 1.0f, 0.0f, 0.0f);
	}
	nodeYZ->AttachChild(meshYZ);

	// xz
	PX2::Node *nodeXZ = new0 Node;
	nodeXZ->SetName("Translate_XZ");
	TriMesh *meshXZ = stdMesh.Rectangle(2, 2, 0.25f, 0.25f);
	meshXZ->LocalTransform.SetRotate(Matrix3f().MakeEulerXYZ(Mathf::HALF_PI, 0.0f, 0.0f));
	meshXZ->LocalTransform.SetTranslate(APoint(0.25f, 0.0f, 0.25f));
	VertexColor4Material *matXZ = new0 VertexColor4Material();
	matXZ->GetAlphaProperty(0, 0)->BlendEnabled = true;
	matXZ->GetCullProperty(0, 0)->Enabled = false;
	meshXZ->SetMaterialInstance(matXZ->CreateInstance());
	vBufferTemp = meshXZ->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(1.0f, 1.0f, 0.0f, 0.0f);
	}
	nodeXZ->AttachChild(meshXZ);

	// XYZ
	node->AttachChild(nodeX);
	node->AttachChild(nodeY);
	node->AttachChild(nodeZ);
	node->AttachChild(nodeXY);
	node->AttachChild(nodeYZ);
	node->AttachChild(nodeXZ);

	return node;
}
//----------------------------------------------------------------------------
PX2::Node *GeoObjFactory::CreateRolateCtrl_P()
{
	int axisSamples = 4;
	int radialSamples = 12;
	float radial = 0.05f;
	float height = radial*4.0f;

	// node
	PX2::Node *node = new0 Node;
	node->LocalTransform.SetUniformScale(2.0f);
	node->SetName("Rolate");

	VertexFormat *vf = PX2_GR.GetVertexFormat(GraphicsRoot::VFT_PC);
	StandardMesh stdMesh(vf);
	VertexBuffer *vBufferTemp = 0;
	VertexBufferAccessor vbaTemp;

	// x
	PX2::Node *nodeX = new0 Node;
	nodeX->SetName("Rolate_X");

	VertexBuffer *vBufferX = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaX(vf, vBufferX);

	vbaX.Position<Float3>(0) = Float3(0.25f, 0.0f, 0.0f);
	vbaX.Position<Float3>(1) = Float3(1.125f, 0.0f, 0.0f);
	vbaX.Color<Float4>(0, 0) = Float4::RED;
	vbaX.Color<Float4>(0, 1) = Float4::RED;

	vbaX.Position<Float3>(2) = Float3(0.5f, 0.0f, 0.0f);
	vbaX.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f);
	vbaX.Color<Float4>(0, 2) = Float4::GREEN;
	vbaX.Color<Float4>(0, 3) = Float4::GREEN;

	vbaX.Position<Float3>(4) = Float3(0.5f, 0.0f, 0.0f);
	vbaX.Position<Float3>(5) = Float3(0.5f, 0.0f, 0.5f);
	vbaX.Color<Float4>(0, 4) = Float4::RED;
	vbaX.Color<Float4>(0, 5) = Float4::RED;

	Polysegment *polysegmentX = new0 PX2::Polysegment(vf, vBufferX,
		false);
	polysegmentX->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeX->AttachChild(polysegmentX);

	TriMesh *meshX = stdMesh.Cylinder(axisSamples, radialSamples, radial,
		height, false);
	meshX->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	meshX->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_Y,
		Mathf::HALF_PI));
	meshX->LocalTransform.SetTranslate(APoint(1.125f, 0.0f, 0.0f));
	vBufferTemp = meshX->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4::RED;
	}
	nodeX->AttachChild(meshX);

	// y
	PX2::Node *nodeY = new0 PX2::Node;
	nodeX->SetName("Rolate_Y");

	VertexBuffer *vBufferY = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaY(vf, vBufferY);

	vbaY.Position<Float3>(0) = Float3(0.0f, 0.25f, 0.0f);
	vbaY.Position<Float3>(1) = Float3(0.0f, 1.125f, 0.0f);
	vbaY.Color<Float4>(0, 0) = Float4::GREEN;
	vbaY.Color<Float4>(0, 1) = Float4::GREEN;

	vbaY.Position<Float3>(2) = Float3(0.0f, 0.5f, 0.0f);
	vbaY.Position<Float3>(3) = Float3(0.5f, 0.5f, 0.0f);
	vbaY.Color<Float4>(0, 2) = Float4::GREEN;
	vbaY.Color<Float4>(0, 3) = Float4::GREEN;

	vbaY.Position<Float3>(4) = Float3(0.0f, 0.5f, 0.0f);
	vbaY.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f);
	vbaY.Color<Float4>(0, 4) = Float4::GREEN;
	vbaY.Color<Float4>(0, 5) = Float4::GREEN;

	Polysegment *polysegmentY = new0 PX2::Polysegment(vf, vBufferY,
		false);
	polysegmentY->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeY->AttachChild(polysegmentY);

	TriMesh *meshY = stdMesh.Cylinder(axisSamples, radialSamples, radial,
		height, false);
	meshY->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	meshY->LocalTransform.SetRotate(HMatrix().MakeRotation(AVector::UNIT_X,
		Mathf::HALF_PI));
	meshY->LocalTransform.SetTranslate(APoint(0.0f, 1.125f, 0.0f));
	vBufferTemp = meshY->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4(0.0f, 1.0f, 0.0f, 1.0f);
	}
	nodeY->AttachChild(meshY);

	// z
	PX2::Node *nodeZ = new0 PX2::Node();
	nodeX->SetName("Rolate_Z");

	VertexBuffer *vBufferZ = new0 VertexBuffer(6, vf->GetStride());
	VertexBufferAccessor vbaZ(vf, vBufferZ);

	vbaZ.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.25f);
	vbaZ.Position<Float3>(1) = Float3(0.0f, 0.0f, 1.125f);
	vbaZ.Color<Float4>(0, 0) = Float4::BLUE;
	vbaZ.Color<Float4>(0, 1) = Float4::BLUE;

	vbaZ.Position<Float3>(2) = Float3(0.0f, 0.0f, 0.5f);
	vbaZ.Position<Float3>(3) = Float3(0.5f, 0.0f, 0.5f);
	vbaZ.Color<Float4>(0, 2) = Float4::BLUE;
	vbaZ.Color<Float4>(0, 3) = Float4::BLUE;

	vbaZ.Position<Float3>(4) = Float3(0.0f, 0.0f, 0.5f);
	vbaZ.Position<Float3>(5) = Float3(0.0f, 0.5f, 0.5f);
	vbaZ.Color<Float4>(0, 4) = Float4::BLUE;
	vbaZ.Color<Float4>(0, 5) = Float4::BLUE;

	Polysegment *polysegmentZ = new0 PX2::Polysegment(vf, vBufferZ,
		false);
	polysegmentZ->SetMaterialInstance(
		VertexColor4Material::CreateUniqueInstance());
	nodeZ->AttachChild(polysegmentZ);

	TriMesh *meshZ = stdMesh.Cylinder(axisSamples, radialSamples, radial,
		height, false);
	meshZ->SetMaterialInstance(VertexColor4Material::CreateUniqueInstance());
	meshZ->LocalTransform.SetTranslate(APoint(.0f, 0.0f, 1.125f));
	vBufferTemp = meshZ->GetVertexBuffer();
	vbaTemp.ApplyTo(vf, vBufferTemp);
	for (int i = 0; i < vBufferTemp->GetNumElements(); i++)
	{
		vbaTemp.Color<Float4>(0, i) = Float4::BLUE;
	}
	nodeZ->AttachChild(meshZ);

	// XYZ
	node->AttachChild(nodeX);
	node->AttachChild(nodeY);
	node->AttachChild(nodeZ);

	return node;
}
//----------------------------------------------------------------------------
void SceneBuilder::ProcessSkin(INode *node, Modifier *skinMod)
{
	// 构造皮肤控制器。如果Max的网格被按照材质细分,每一个网格都需要自己的蒙皮
	// 信息控制器。蒙皮信息中的offset,在动画起始时被计算,是骨骼的世界变换。
	//
	// node:
	//		指向蒙皮修改器指向的Max中的节点。
	// skinMod:
	//		指向蒙皮修改器

	// 1. 获得max蒙皮信息中的骨骼,对应的在Phoenix的骨骼节点列表
	// 2. 获得maxNode影响的Phoenix网格
	// 3. 获得max中每个骨骼所影响的Phoenix网格中的顶点的数量,忽略不受蒙皮信息
	//	  影响的网格
	// 4. 计算Phoenix mesh的蒙皮信息,生成SkinControl,AttachController到
	//    Phoenix mesh上。
	
	// 1

	bool needDel;
	TriObject *triObj = GetTriObject(node, &needDel);
	Mesh *maxMesh = &triObj->GetMesh();

	// Max皮肤控制器接口
	ISkin *skin = (ISkin*)skinMod->GetInterface(I_SKIN);
	ISkinContextData *skinData = skin->GetContextInterface(node);

	// max Skin Bones -> Phoenix2 Skin Bones
	int b, numSkinBone = skin->GetNumBones();
	PX2::Node **bones = new1<PX2::Node*>(numSkinBone);
	for (b=0; b<numSkinBone; b++)
	{
		INode *boneNode = skin->GetBone(b);
		const std::string &boneName = boneNode->GetName();
		PX2::Node *node = PX2::StaticCast<PX2::Node>(mScene->GetObjectByName(boneName));
		bones[b] = node;
	}

	// 1

	// 获得maxNode相关联的Phoenix mesh
	std::vector<PX2::TriMesh*> meshes;
	PX2::Object *object = mScene->GetObjectByName(node->GetName());
	if (object->IsExactly(PX2::TriMesh::TYPE))
	{
		meshes.push_back(PX2::StaticCast<PX2::TriMesh>(object));
	}
	else
	{
		PX2::Node *node = PX2::StaticCast<PX2::Node>(object);
		const char *nName = node->GetName().c_str();
		for (int c=0; c<node->GetNumChildren(); c++)
		{
			PX2::Movable *child = node->GetChild(c);
			const char *cName = child->GetName().c_str();
			if (strncmp(cName, nName, strlen(nName)) == 0) // 这里必须是strlen(nName),因为子节点有_1,_2
			{
				meshes.push_back(PX2::StaticCast<PX2::TriMesh>(child));
			}
		}
	}

	// 为Phoenix2的每个网格建立相关的皮肤控制器

	int *boneInfuseNumVert = new1<int>(numSkinBone);
	for (int m=0; m<(int)meshes.size(); m++)
	{
		PX2::TriMesh *mesh = meshes[m];

		// Phoenix顶点在max顶点中的索引
		PX2::VertexBuffer *vb = mesh->GetVertexBuffer();
		int px2MeshVertexNum = vb->GetNumElements();
		std::vector<int> MaxVertexIndex; // i->max索引
		int v, i, j, k;

		PX2::VertexBufferAccessor vba(mesh->GetVertexFormat(), vb);

		// 3

		for (int v=0; v<px2MeshVertexNum; ++v)
		{
			Float3 &position = vba.Position<Float3>(v);
			for (i=0; i<maxMesh->getNumVerts(); i++)
			{
				if (position[0] == maxMesh->verts[i].x
					&& position[1] == maxMesh->verts[i].y 
					&& position[2] == maxMesh->verts[i].z)
				{
					MaxVertexIndex.push_back(i);
					break;
				}
			}
		}

		// 确定每个骨骼所影响的顶点数量
		int maxVertexSize = (int)MaxVertexIndex.size();
		memset(boneInfuseNumVert, 0, sizeof(int)*numSkinBone);
		for (i=0; i<maxVertexSize; i++)
		{
			v = MaxVertexIndex[i];
			for (j=0; j<skinData->GetNumAssignedBones(v); j++)
			{ // 这个max中的顶点受到几个骨骼影响啊?!
				b = skinData->GetAssignedBone(v, j); // 获得这个影响的骨骼索引(这个j是第几个)
				boneInfuseNumVert[b]++; // 这个骨骼影响的顶点数量++
			}
		}

		// (通过PX2中的顶点找到Max中的顶点,找到Max中影响该顶点的骨骼)

		// 如果Max的网格是被按照材质分割的,可能一些骨骼对当前Phoenix2网格没有
		// 影响
		int bQuantity = 0; // 影响当前Phoenix2网格的骨骼数量
		for (b=0; b<numSkinBone; b++)
		{
			if (boneInfuseNumVert[b] > 0)
				bQuantity++;
		}

		if (bQuantity == 0)
		{
			// Phoenix网格不被任何骨骼影响,进入下一个网格
			continue;
		}

		// 4

		PX2::Node **theBones = new1<PX2::Node*>(bQuantity);
		float **weight = new2<float>(bQuantity, maxVertexSize);
		memset(weight[0],0,bQuantity*maxVertexSize*sizeof(float));
		PX2::APoint **offset = new2<PX2::APoint>(bQuantity, maxVertexSize);
		memset(offset[0],0,bQuantity*maxVertexSize*sizeof(PX2::APoint));
		PX2::HMatrix *mats = new1<PX2::HMatrix>(bQuantity);

		// 计算max骨骼到Phoenix骨骼对应的索引(k)
		std::vector<int> bIArray(numSkinBone);
		for (b=0, k=0; b<numSkinBone; b++)
		{
			if (boneInfuseNumVert[b] > 0)
			{
				theBones[k] = bones[b]; // 获取对Mesh有影响的骨骼
				bIArray[b] = k; // max bone index -> px2 可用bone index
				
				HMatrix boneWorldMat = theBones[k]->WorldTransform.Matrix();
				HMatrix meshWorldMat =  mesh->WorldTransform.Matrix();

				mats[k] = boneWorldMat.Inverse() * meshWorldMat;
				
				k++;
			}
		}

		// 遍历顶点,计算顶点权重和offset
		for (i=0; i<maxVertexSize; i++)
		{
			v = MaxVertexIndex[i];
			for (j=0; j<skinData->GetNumAssignedBones(v); j++)
			{ // 遍历影响该Max顶点的骨骼
				b = skinData->GetAssignedBone(v, j);
				k = bIArray[b];
				float wit = skinData->GetBoneWeight(v, j); // 第j个骨骼的影响权重
				weight[i][k] = wit;

				Float3 &position = vba.Position<Float3>(i);

				APoint point = theBones[k]->WorldTransform.Inverse() 
					* (mesh->WorldTransform * APoint(position));
				offset[i][k] = Float3(point.X(), point.Y(), point.Z()); // 在所受影响骨骼中的位置
			}
		}

		PX2::SkinController *skinCtrl = new0 PX2::SkinController
			(maxVertexSize, bQuantity);
		skinCtrl->SetName("SkinController");
		for (int i=0; i<bQuantity; i++)
		{
			skinCtrl->GetBones()[i] = theBones[i];
			skinCtrl->GetTMMatrixs()[i] = mats[i];
		}

		// offset
		for (int i=0; i<maxVertexSize; i++)
		{
			for (int j=0; j<bQuantity; j++)
			{
				skinCtrl->GetWeights()[i][j] = weight[i][j];
				skinCtrl->GetOffsets()[i][j] = offset[i][j]; 
			}
		}

		// index weights
		for (int i=0; i<maxVertexSize; i++)
		{
			Float4 inds = Float4(0.0f, 0.0f, 0.0f, 0.0f);
			Float4 wights = Float4(0.0f, 0.0f, 0.0f, 0.0f);

			In *pSortBone = new In[bQuantity];
			for (int j=0; j<bQuantity; j++)
			{
				pSortBone[j].index = j;
				pSortBone[j].data = weight[i][j];
			}
			qsort(pSortBone, bQuantity, sizeof(pSortBone[0]), cmp);

			int useBoneNum = bQuantity;
			if (useBoneNum > 4)
				useBoneNum = 4;

			float allWeight = 0.0f;
			for (int useBoneIndex=0; useBoneIndex<useBoneNum; useBoneIndex++)
			{
				allWeight += pSortBone[useBoneIndex].data;
			}
			if (allWeight <= 0.0f)
				allWeight = 1.0f;

			for (int useBoneIndex=0; useBoneIndex<useBoneNum; useBoneIndex++)
			{
				inds[useBoneIndex] = (float)(pSortBone[useBoneIndex].index);
				wights[useBoneIndex] = pSortBone[useBoneIndex].data/allWeight;
			}

			vba.TCoord<Float4>(1, i) = inds;
			vba.TCoord<Float4>(2, i) = wights;

			delete [] pSortBone;
		}
		
		skinCtrl->Repeat = Controller::RT_WRAP;
		skinCtrl->MinTime = 0.0f;
		skinCtrl->MaxTime = TicksToSec(mTimeEnd - mTimeStart);

		mesh->AttachController(skinCtrl);

		delete1(theBones);
		delete2(weight);
		delete2(offset);
		delete1(mats);
	}

	if (needDel)
	{
		delete0(triObj);
	}

	delete1(bones);
	delete1(boneInfuseNumVert);
}