Пример #1
0
//----------------------------------------------------------------------------
Node* RoughPlaneSolidBox::CreateBox ()
{
    mBox = new0 Node();

    float xExtent = (float)mModule.XLocExt;
    float yExtent = (float)mModule.YLocExt;
    float zExtent = (float)mModule.ZLocExt;

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);

    StandardMesh sm(vformat);
    VertexColor3Effect* effect = new0 VertexColor3Effect();
    VertexBufferAccessor vba;
    Transform transform;
    TriMesh* face;
    int i;

    // +z face
    Float3 red(1.0f, 0.0f, 0.0f);
    transform.SetTranslate(APoint(0.0f, 0.0f, zExtent));
    sm.SetTransform(transform);
    face = sm.Rectangle(2, 2, xExtent, yExtent);
    vba.ApplyTo(face);
    for (i = 0; i < 4; ++i)
    {
        vba.Color<Float3>(0, 0) = red;
        vba.Color<Float3>(0, 1) = red;
        vba.Color<Float3>(0, 2) = red;
        vba.Color<Float3>(0, 3) = red;
    }
    face->SetEffectInstance(effect->CreateInstance());
    mBox->AttachChild(face);

    // -z face
    Float3 darkRed(0.5f, 0.0f, 0.0f);
    transform.SetTranslate(APoint(0.0f, 0.0f, -zExtent));
    transform.SetRotate(HMatrix(AVector::UNIT_Y, AVector::UNIT_X,
        -AVector::UNIT_Z, APoint::ORIGIN, true));
    sm.SetTransform(transform);
    face = sm.Rectangle(2, 2, yExtent, xExtent);
    vba.ApplyTo(face);
    for (i = 0; i < 4; ++i)
    {
        vba.Color<Float3>(0, 0) = darkRed;
        vba.Color<Float3>(0, 1) = darkRed;
        vba.Color<Float3>(0, 2) = darkRed;
        vba.Color<Float3>(0, 3) = darkRed;
    }
    face->SetEffectInstance(effect->CreateInstance());
    mBox->AttachChild(face);

    // +y face
    Float3 green(0.0f, 1.0f, 0.0f);
    transform.SetTranslate(APoint(0.0f, yExtent, 0.0f));
    transform.SetRotate(HMatrix(AVector::UNIT_Z, AVector::UNIT_X,
        AVector::UNIT_Y, APoint::ORIGIN, true));
    sm.SetTransform(transform);
    face = sm.Rectangle(2, 2, zExtent, xExtent);
    vba.ApplyTo(face);
    for (i = 0; i < 4; ++i)
    {
        vba.Color<Float3>(0, 0) = green;
        vba.Color<Float3>(0, 1) = green;
        vba.Color<Float3>(0, 2) = green;
        vba.Color<Float3>(0, 3) = green;
    }
    face->SetEffectInstance(effect->CreateInstance());
    mBox->AttachChild(face);

    // -y face
    Float3 darkGreen(0.0f, 1.0f, 0.0f);
    transform.SetTranslate(APoint(0.0f, -yExtent, 0.0f));
    transform.SetRotate(HMatrix(AVector::UNIT_X, AVector::UNIT_Z,
        -AVector::UNIT_Y, APoint::ORIGIN, true));
    sm.SetTransform(transform);
    face = sm.Rectangle(2, 2, xExtent, zExtent);
    vba.ApplyTo(face);
    for (i = 0; i < 4; ++i)
    {
        vba.Color<Float3>(0, 0) = darkGreen;
        vba.Color<Float3>(0, 1) = darkGreen;
        vba.Color<Float3>(0, 2) = darkGreen;
        vba.Color<Float3>(0, 3) = darkGreen;
    }
    face->SetEffectInstance(effect->CreateInstance());
    mBox->AttachChild(face);

    // +x face
    Float3 blue(0.0f, 0.0f, 1.0f);
    transform.SetTranslate(APoint(xExtent, 0.0f, 0.0f));
    transform.SetRotate(HMatrix(AVector::UNIT_Y, AVector::UNIT_Z,
        AVector::UNIT_X, APoint::ORIGIN, true));
    sm.SetTransform(transform);
    face = sm.Rectangle(2, 2, yExtent, zExtent);
    vba.ApplyTo(face);
    for (i = 0; i < 4; ++i)
    {
        vba.Color<Float3>(0, 0) = blue;
        vba.Color<Float3>(0, 1) = blue;
        vba.Color<Float3>(0, 2) = blue;
        vba.Color<Float3>(0, 3) = blue;
    }
    face->SetEffectInstance(effect->CreateInstance());
    mBox->AttachChild(face);

    // -x face
    Float3 darkBlue(0.0f, 0.0f, 1.0f);
    transform.SetTranslate(APoint(-xExtent, 0.0f, 0.0f));
    transform.SetRotate(HMatrix(AVector::UNIT_Z, AVector::UNIT_Y,
        -AVector::UNIT_X, APoint::ORIGIN, true));
    sm.SetTransform(transform);
    face = sm.Rectangle(2, 2, zExtent, yExtent);
    vba.ApplyTo(face);
    for (i = 0; i < 4; ++i)
    {
        vba.Color<Float3>(0, 0) = darkBlue;
        vba.Color<Float3>(0, 1) = darkBlue;
        vba.Color<Float3>(0, 2) = darkBlue;
        vba.Color<Float3>(0, 3) = darkBlue;
    }
    face->SetEffectInstance(effect->CreateInstance());
    mBox->AttachChild(face);

    MoveBox();
    return mBox;
}
Пример #2
0
//----------------------------------------------------------------------------
void CubeMaps::CreateScene ()
{
	// Create the root of the scene.
	mScene = new0 Node();
	mWireState = new0 WireState();
	mRenderer->SetOverrideWireState(mWireState);

	// Create the walls of the cube room.  Each of the six texture images is
	// RGBA 64-by-64.
	Node* room = new0 Node();
	mScene->AttachChild(room);

	// Index buffer shared by the room walls.
	IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int));
	int* indices = (int*)ibuffer->GetData();
	indices[0] = 0;
	indices[1] = 1;
	indices[2] = 3;
	indices[3] = 0;
	indices[4] = 3;
	indices[5] = 2;

	// The vertex format shared by the room walls.
	VertexFormat* vformat = VertexFormat::Create(2,
	                        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);
	int vstride = vformat->GetStride();
	VertexBufferAccessor vba;

	// The texture effect shared by the room walls.
	Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR);

	VertexBuffer* vbuffer;
	TriMesh* wall;
	std::string textureName;

	// +x wall
	vbuffer = new0 VertexBuffer(4, vstride);
	vba.ApplyTo(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f);
	vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, +1.0f);
	vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f);
	vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, +1.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
	vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
	vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
	vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
	wall = new0 TriMesh(vformat, vbuffer, ibuffer);
	room->AttachChild(wall);
	textureName = Environment::GetPathR("XpFace.wmtf");
	Texture2D* xpTexture = Texture2D::LoadWMTF(textureName);
	wall->SetEffectInstance(effect->CreateInstance(xpTexture));

	// -x wall
	vbuffer = new0 VertexBuffer(4, vstride);
	vba.ApplyTo(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, +1.0f);
	vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f);
	vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, +1.0f);
	vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
	vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
	vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
	vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
	wall = new0 TriMesh(vformat, vbuffer, ibuffer);
	room->AttachChild(wall);
	textureName = Environment::GetPathR("XmFace.wmtf");
	Texture2D* xmTexture = Texture2D::LoadWMTF(textureName);
	wall->SetEffectInstance(effect->CreateInstance(xmTexture));

	// +y wall
	vbuffer = new0 VertexBuffer(4, vstride);
	vba.ApplyTo(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(+1.0f, +1.0f, +1.0f);
	vba.Position<Float3>(1) = Float3(-1.0f, +1.0f, +1.0f);
	vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, -1.0f);
	vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, -1.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
	vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
	vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
	vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
	wall = new0 TriMesh(vformat, vbuffer, ibuffer);
	room->AttachChild(wall);
	textureName = Environment::GetPathR("YpFace.wmtf");
	Texture2D* ypTexture = Texture2D::LoadWMTF(textureName);
	wall->SetEffectInstance(effect->CreateInstance(ypTexture));

	// -y wall
	vbuffer = new0 VertexBuffer(4, vstride);
	vba.ApplyTo(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, -1.0f);
	vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, -1.0f);
	vba.Position<Float3>(2) = Float3(+1.0f, -1.0f, +1.0f);
	vba.Position<Float3>(3) = Float3(-1.0f, -1.0f, +1.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
	vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
	vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
	vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
	wall = new0 TriMesh(vformat, vbuffer, ibuffer);
	room->AttachChild(wall);
	textureName = Environment::GetPathR("YmFace.wmtf");
	Texture2D* ymTexture = Texture2D::LoadWMTF(textureName);
	wall->SetEffectInstance(effect->CreateInstance(ymTexture));

	// +z wall
	vbuffer = new0 VertexBuffer(4, vstride);
	vba.ApplyTo(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(+1.0f, -1.0f, +1.0f);
	vba.Position<Float3>(1) = Float3(-1.0f, -1.0f, +1.0f);
	vba.Position<Float3>(2) = Float3(+1.0f, +1.0f, +1.0f);
	vba.Position<Float3>(3) = Float3(-1.0f, +1.0f, +1.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
	vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
	vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
	vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
	wall = new0 TriMesh(vformat, vbuffer, ibuffer);
	room->AttachChild(wall);
	textureName = Environment::GetPathR("ZpFace.wmtf");
	Texture2D* zpTexture = Texture2D::LoadWMTF(textureName);
	wall->SetEffectInstance(effect->CreateInstance(zpTexture));

	// -z wall
	vbuffer = new0 VertexBuffer(4, vstride);
	vba.ApplyTo(vformat, vbuffer);
	vba.Position<Float3>(0) = Float3(-1.0f, -1.0f, -1.0f);
	vba.Position<Float3>(1) = Float3(+1.0f, -1.0f, -1.0f);
	vba.Position<Float3>(2) = Float3(-1.0f, +1.0f, -1.0f);
	vba.Position<Float3>(3) = Float3(+1.0f, +1.0f, -1.0f);
	vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f);
	vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f);
	vba.TCoord<Float2>(0, 2) = Float2(0.0f, 1.0f);
	vba.TCoord<Float2>(0, 3) = Float2(1.0f, 1.0f);
	wall = new0 TriMesh(vformat, vbuffer, ibuffer);
	room->AttachChild(wall);
	textureName = Environment::GetPathR("ZmFace.wmtf");
	Texture2D* zmTexture = Texture2D::LoadWMTF(textureName);
	wall->SetEffectInstance(effect->CreateInstance(zmTexture));

	// A sphere to reflect the environment via a cube map.  The colors will
	// be used to modulate the cube map texture.
	vformat = VertexFormat::Create(3,
	                               VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                               VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0,
	                               VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
	vstride = vformat->GetStride();

	mSphere = StandardMesh(vformat).Sphere(64, 64, 0.125f);
	room->AttachChild(mSphere);

	// Generate random vertex colors for the sphere.  The StandardMesh class
	// produces a sphere with duplicated vertices along a longitude line.
	// This allows texture coordinates to be assigned in a manner that treats
	// the sphere as if it were a rectangle mesh.  For vertex colors, we want
	// the duplicated vertices to have the same color, so a hash table is used
	// to look up vertex colors for the duplicates.
	vba.ApplyTo(mSphere);
	std::map<Float3,Float3> dataMap;
	for (int i = 0; i < vba.GetNumVertices(); ++i)
	{
		Float3& position = vba.Position<Float3>(i);
		Float3& color = vba.Color<Float3>(0, i);
		std::map<Float3,Float3>::iterator iter = dataMap.find(position);
		if (iter != dataMap.end())
		{
			color = iter->second;
		}
		else
		{
			color[0] = 0.0f;
			color[1] = Mathf::IntervalRandom(0.5f, 0.75f);
			color[2] = Mathf::IntervalRandom(0.75f, 1.0f);
			dataMap.insert(std::make_pair(position, color));
		}
	}

	// Create the cube map and attach it to the sphere.
	std::string effectFile = Environment::GetPathR("CubeMap.wmfx");
	CubeMapEffect* cubeMapEffect = new0 CubeMapEffect(effectFile);

	ShaderFloat* reflectivity = new0 ShaderFloat(1);
	(*reflectivity)[0] = 0.5f;

	std::string cubeName = Environment::GetPathR("CubeMap.wmtf");
	TextureCube* cubeTexture = TextureCube::LoadWMTF(cubeName);
	cubeTexture->GenerateMipmaps();
	mCubeMapInstance = cubeMapEffect->CreateInstance(cubeTexture,
	                   reflectivity, false);

	mSphere->SetEffectInstance(mCubeMapInstance);

	// Allow culling to be disabled on the sphere so when you move inside
	// the sphere, you can see the previously hidden facets and verify that
	// the cube image for those facets is correctly oriented.
	mSphereCullState = cubeMapEffect->GetCullState(0, 0);
}
Пример #3
0
//----------------------------------------------------------------------------
void Billboard::GenBuffers ()
{
	Effectable::GenBuffers();

	BillboardController *billCtrl = DynamicCast<BillboardController>(
		mEffectableCtrl);
	const EffectObject *billboardObject = billCtrl->GetBillboardObject();
	if (!billboardObject)
		return;

	float age = billboardObject->Age;

	float uBegin = billboardObject->UV0Begin[0];
	float uEnd =  billboardObject->UV0End[0];
	float vBegin =  billboardObject->UV0Begin[1];
	float vEnd =  billboardObject->UV0End[1];
	int uvIndex = GetUV(billboardObject->StartRandomIndex, 
		age, uBegin, uEnd, vBegin, vEnd);

	float xPlusPer = 0.0f;
	float zPlusPer = 0.0f;
	float widthPer = 1.0f;
	float heightPer = 1.0f;

	if (IsUseTrim() && Effectable::TM_TEXPACK_ANIM==GetTexMode() && mTexPackAnim_Frames.size()>0)
	{
		if (0 != mTexPackAnim_Frames[uvIndex].OW)
		{
			xPlusPer = (float)mTexPackAnim_Frames[uvIndex].OX
				/ (float)mTexPackAnim_Frames[uvIndex].OW;
			widthPer = (float)mTexPackAnim_Frames[uvIndex].W
				/(float)mTexPackAnim_Frames[uvIndex].OW;
		}
		if (0 != mTexPackAnim_Frames[uvIndex].OH)
		{
			zPlusPer = 1.0f -
				(float)(mTexPackAnim_Frames[uvIndex].OY+mTexPackAnim_Frames[uvIndex].H)
				/ (float)mTexPackAnim_Frames[uvIndex].OH;
			heightPer = (float)mTexPackAnim_Frames[uvIndex].H
				/(float)mTexPackAnim_Frames[uvIndex].OH;
		}
	}

	float width = billboardObject->SizeX;
	float height = billboardObject->SizeY;

	float xPos = 0.0f - width * mPivotPoint[0];
	float zPos = 0.0f - height * mPivotPoint[1];
	xPos += xPlusPer * width;
	zPos += zPlusPer * height;	

	width *= widthPer;
	height *= heightPer;

	Float3 color = billboardObject->Color;
	float alpha = billboardObject->Alpha;

	Float3 p0;
	Float3 p1;
	Float3 p2;
	Float3 p3;
	FaceType faceType = GetFaceType();
	if (FT_X == faceType)
	{
		p0 = Float3(0.0f,		xPos,		zPos);
		p1 = Float3(0.0f,		xPos+width,	zPos);
		p2 = Float3(0.0f,		xPos,		zPos+height);
		p3 = Float3(0.0f,		xPos+width, zPos+height);
	}
	else if (FT_NX == faceType)
	{
		p0 = Float3(0.0f,		-xPos,			zPos);
		p1 = Float3(0.0f,		-(xPos+width),	zPos);
		p2 = Float3(0.0f,		-xPos,			zPos+height);
		p3 = Float3(0.0f,		-(xPos+width),	zPos+height);
	}
	else if (FT_Y == faceType)
	{
		p0 = Float3(-xPos,			0.0f,		zPos);
		p1 = Float3(-(xPos+width),	0.0f,		zPos);
		p2 = Float3(-xPos,			0.0f,		zPos+height);
		p3 = Float3(-(xPos+width),	0.0f,		zPos+height);
	}
	else if (FT_NY == faceType)
	{
		p0 = Float3(xPos,		0.0f,		zPos);
		p1 = Float3(xPos+width,	0.0f,		zPos);
		p2 = Float3(xPos,		0.0f,		zPos+height);
		p3 = Float3(xPos+width, 0.0f,		zPos+height);
	}
	else if (FT_Z == faceType)
	{
		p0 = Float3(xPos,		zPos,			0.0f);
		p1 = Float3(xPos+width,	zPos,			0.0f);
		p2 = Float3(xPos,		zPos+height,	0.0f);
		p3 = Float3(xPos+width,	zPos+height,	0.0f);
	}
	else if (FT_NZ == faceType)
	{
		p0 = Float3(-xPos,			zPos,			0.0f);
		p1 = Float3(-(xPos+width),	zPos,			0.0f);
		p2 = Float3(-xPos,			zPos+height,	0.0f);
		p3 = Float3(-(xPos+width),	zPos+height,	0.0f);
	}
	else if (FT_CAMERA == faceType)
	{
		Camera *camera = PX2_GR.GetCurUpdateCamera();
		if (!camera)
			return;

		const AVector &camUp = camera->GetUVector();
		const AVector &camRight = camera->GetRVector();

		float anchorWidth = mPivotPoint[0]*width;
		float anchorHeight = mPivotPoint[1]*height;

		APoint position;
		p0 = position 
			- camRight * anchorWidth
			- camUp * anchorHeight;

		p1 = position 
			+ camRight * (width-anchorWidth)
			- camUp * anchorHeight;

		p2 = position 
			- camRight * anchorWidth
			+ camUp * (height-anchorHeight);

		p3 = position 
			+ camRight * (width-anchorWidth)
			+ camUp * (height-anchorHeight);
	}
	else if (FT_SPEEDDIR==faceType || FT_FREE==faceType)
	{
		p0 = Float3(xPos,		0.0f,		zPos);
		p1 = Float3(xPos+width,	0.0f,		zPos);
		p2 = Float3(xPos,		0.0f,		zPos+height);
		p3 = Float3(xPos+width, 0.0f,		zPos+height);
	}

	//SetUseShareBuffers(true);
	if (!IsUseShareBuffers())
	{
		VertexBufferAccessor vba(this);
		vba.Position<Float3>(0) = p0;
		vba.Position<Float3>(1) = p1;
		vba.Position<Float3>(2) = p2;
		vba.Position<Float3>(3) = p3;

		vba.Color<Float4>(0, 0) = Float4(color[0], color[1], color[2], alpha);
		vba.Color<Float4>(0, 1) = Float4(color[0], color[1], color[2], alpha);
		vba.Color<Float4>(0, 2) = Float4(color[0], color[1], color[2], alpha);
		vba.Color<Float4>(0, 3) = Float4(color[0], color[1], color[2], alpha);
		vba.TCoord<Float2>(0, 0) = Float2(uBegin, vBegin);
		vba.TCoord<Float2>(0, 1) = Float2(uEnd, vBegin);
		vba.TCoord<Float2>(0, 2) = Float2(uBegin, vEnd);
		vba.TCoord<Float2>(0, 3) = Float2(uEnd, vEnd);

		if (!IsFixedBound())
			UpdateModelSpace(GU_MODEL_BOUND_ONLY);

		Renderer::UpdateAll(GetVertexBuffer());
	}
	else
	{
		mDBObject_V = PX2_DBM.AllocVertexBuffer(4);
		mDBObject_I = PX2_DBM.AllocIndexBuffer(6);

		SetShareDBObject_V(mDBObject_V);
		SetShareDBObject_I(mDBObject_I);

		VertexBufferAccessor vba;
		vba.ApplyTo(GetVertexFormat(), mDBObject_V->Buf);

		vba.Position<Float3>(mDBObject_V->Offset+0) = p0;
		vba.Position<Float3>(mDBObject_V->Offset+1) = p1;
		vba.Position<Float3>(mDBObject_V->Offset+2) = p2;
		vba.Position<Float3>(mDBObject_V->Offset+3) = p3;

		vba.Color<Float4>(0, mDBObject_V->Offset+0) = Float4(color[0], color[1], color[2], alpha);
		vba.Color<Float4>(0, mDBObject_V->Offset+1) = Float4(color[0], color[1], color[2], alpha);
		vba.Color<Float4>(0, mDBObject_V->Offset+2) = Float4(color[0], color[1], color[2], alpha);
		vba.Color<Float4>(0, mDBObject_V->Offset+3) = Float4(color[0], color[1], color[2], alpha);
		vba.TCoord<Float2>(0, mDBObject_V->Offset+0) = Float2(uBegin, vBegin);
		vba.TCoord<Float2>(0, mDBObject_V->Offset+1) = Float2(uEnd, vBegin);
		vba.TCoord<Float2>(0, mDBObject_V->Offset+2) = Float2(uBegin, vEnd);
		vba.TCoord<Float2>(0, mDBObject_V->Offset+3) = Float2(uEnd, vEnd);

		unsigned short *indices = (unsigned short*)mDBObject_I->Buf->GetData();
		indices += mDBObject_I->Offset;

		unsigned short v0 = (unsigned short)(mDBObject_V->Offset+0);
		unsigned short v1 = (unsigned short)(mDBObject_V->Offset+1);
		unsigned short v2 = (unsigned short)(mDBObject_V->Offset+2);
		unsigned short v3 = (unsigned short)(mDBObject_V->Offset+3);
		*indices++ = v0;
		*indices++ = v1;
		*indices++ = v2;
		*indices++ = v1;
		*indices++ = v3;
		*indices++ = v2;
	}
}
Пример #4
0
//----------------------------------------------------------------------------
void BspNodes::CreateScene ()
{
	// Create the scene graph.
	//
	// 1. The rectangles represent the BSP planes of the BSP tree.  They
	//    share a VertexColor3Effect.  You can see a plane from either side
	//    (backface culling disabled).  The planes do not interfere with view
	//    of the solid objects (wirestate enabled).
	//
	// 2. The sphere, tetrahedron, and cube share a TextureEffect.  These
	//    objects are convex.  The backfacing triangles are discarded
	//    (backface culling enabled).  The front facing triangles are drawn
	//    correctly by convexity, so depthbuffer reads are disabled and
	//    depthbuffer writes are enabled.  The BSP-based sorting of objects
	//    guarantees that front faces of convex objects in the foreground
	//    are drawn after the front faces of convex objects in the background,
	//    which allows us to set the depthbuffer state as we have.  That is,
	//    BSPNode sorts from back to front.
	//
	// 3. The torus has backface culling enabled and depth buffering enabled.
	//    This is necessary, because the torus is not convex.
	//
	// 4. Generally, if all objects are opaque, then you want to draw from
	//    front to back with depth buffering fully enabled.  You need to
	//    reverse-order the elements of the visible set before drawing.  If
	//    any of the objects are semitransparent, then drawing back to front
	//    is the correct order to handle transparency.  However, you do not
	//    get the benefit of early z-rejection for opaque objects.  A better
	//    BSP sorter needs to be built to produce a visible set with opaque
	//    objects listed first (front-to-back order) and semitransparent
	//    objects listed last (back-to-front order).
	//
	// scene
	//     ground
	//     bsp0
	//         bsp1
	//             bsp3
	//                 torus
	//                 rectangle3
	//                 sphere
	//             rectangle1
	//             tetrahedron
	//         rectangle0
	//         bsp2
	//             cube
	//             rectangle2
	//             octahedron

	mScene = new0 Node();

	// Create the ground.  It covers a square with vertices (1,1,0), (1,-1,0),
	// (-1,1,0), and (-1,-1,0).  Multiply the texture coordinates by a factor
	// to enhance the wrap-around.
	VertexFormat* vformat = VertexFormat::Create(2,
	                        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                        VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0);

	StandardMesh sm(vformat);
	VertexBufferAccessor vba;

	TriMesh* ground = sm.Rectangle(2, 2, 16.0f, 16.0f);
	vba.ApplyTo(ground);
	for (int i = 0; i < vba.GetNumVertices(); ++i)
	{
		Float2& tcoord = vba.TCoord<Float2>(0, i);
		tcoord[0] *= 128.0f;
		tcoord[1] *= 128.0f;
	}

	std::string path = Environment::GetPathR("Horizontal.wmtf");
	Texture2D* texture = Texture2D::LoadWMTF(path);
	ground->SetEffectInstance(Texture2DEffect::CreateUniqueInstance(texture,
	                          Shader::SF_LINEAR_LINEAR, Shader::SC_REPEAT, Shader::SC_REPEAT));
	mScene->AttachChild(ground);

	// Partition the region above the ground into 5 convex pieces.  Each plane
	// is perpendicular to the ground (not required generally).
	VertexColor3Effect* vceffect = new0 VertexColor3Effect();
	vceffect->GetCullState(0, 0)->Enabled = false;
	vceffect->GetWireState(0, 0)->Enabled = true;

	Vector2f v0(-1.0f, 1.0f);
	Vector2f v1(1.0f, -1.0f);
	Vector2f v2(-0.25f, 0.25f);
	Vector2f v3(-1.0f, -1.0f);
	Vector2f v4(0.0f, 0.0f);
	Vector2f v5(1.0f, 0.5f);
	Vector2f v6(-0.75f, -7.0f/12.0f);
	Vector2f v7(-0.75f, 0.75f);
	Vector2f v8(1.0f, 1.0f);

	BspNode* bsp0 = CreateNode(v0, v1, vceffect, Float3(1.0f, 0.0f, 0.0f));
	BspNode* bsp1 = CreateNode(v2, v3, vceffect, Float3(0.0f, 0.5f, 0.0f));
	BspNode* bsp2 = CreateNode(v4, v5, vceffect, Float3(0.0f, 0.0f, 1.0f));
	BspNode* bsp3 = CreateNode(v6, v7, vceffect, Float3(0.0f, 0.0f, 0.0f));

	bsp0->AttachPositiveChild(bsp1);
	bsp0->AttachNegativeChild(bsp2);
	bsp1->AttachPositiveChild(bsp3);

	// Attach an object in each convex region.
	float height = 0.1f;
	Vector2f center;
	TriMesh* mesh;

	// The texture effect for the convex objects.
	Texture2DEffect* cvxeffect =
	    new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR);
	cvxeffect->GetDepthState(0, 0)->Enabled = false;
	cvxeffect->GetDepthState(0, 0)->Writable = true;

	// The texture effect for the torus.
	Texture2DEffect* toreffect =
	    new0 Texture2DEffect(Shader::SF_LINEAR_LINEAR);

	// The texture image shared by the objects.
	path = Environment::GetPathR("Flower.wmtf");
	texture = Texture2D::LoadWMTF(path);

	// Region 0: Create a torus mesh.
	mesh = sm.Torus(16, 16, 1.0f, 0.25f);
	mesh->SetEffectInstance(toreffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v2 + v6 + v7)/3.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp3->AttachPositiveChild(mesh);

	// Region 1: Create a sphere mesh.
	mesh = sm.Sphere(32, 16, 1.0f);
	mesh->SetEffectInstance(cvxeffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v0 + v3 + v6 + v7)/4.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp3->AttachNegativeChild(mesh);

	// Region 2: Create a tetrahedron.
	mesh = sm.Tetrahedron();
	mesh->SetEffectInstance(cvxeffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v1 + v2 + v3)/3.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp1->AttachNegativeChild(mesh);

	// Region 3: Create a hexahedron (cube).
	mesh = sm.Hexahedron();
	mesh->SetEffectInstance(cvxeffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v1 + v4 + v5)/3.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp2->AttachPositiveChild(mesh);

	// Region 4: Create an octahedron.
	mesh = sm.Octahedron();
	mesh->SetEffectInstance(cvxeffect->CreateInstance(texture));
	mesh->LocalTransform.SetUniformScale(0.1f);
	center = (v0 + v4 + v5 + v8)/4.0f;
	mesh->LocalTransform.SetTranslate(APoint(center[0], center[1], height));
	bsp2->AttachNegativeChild(mesh);

	mScene->AttachChild(bsp0);
}
Пример #5
0
//----------------------------------------------------------------------------
void IntersectInfiniteCylinders::CreateScene ()
{
    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    StandardMesh sm(vformat);
    VertexBufferAccessor vba;
    int i;

    // Create the canonical cylinder.
    mCylinder0 = sm.Cylinder(32, 128, mRadius0, mHeight, true);
    mScene->AttachChild(mCylinder0);
    mVisible.Insert(mCylinder0);
    vba.ApplyTo(mCylinder0);
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.Color<Float3>(0, i) = Float3(0.5f, 0.0f, 0.0f);
    }
    mCylinder0->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());

    // Create the other cylinder.
    mCylinder1 = sm.Cylinder(32, 128, mRadius1, mHeight, true);
    mScene->AttachChild(mCylinder1);
    mVisible.Insert(mCylinder1);
    vba.ApplyTo(mCylinder1);
    for (i = 0; i < vba.GetNumVertices(); ++i)
    {
        vba.Color<Float3>(0, i) = Float3(0.0f, 0.0f, 0.5f);
    }
    mCylinder1->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());
    mCylinder1->LocalTransform.SetRotate(HMatrix(AVector::UNIT_X, -mAngle));
    mCylinder1->LocalTransform.SetTranslate(APoint(mC0, 0.0f, 0.0f));

    // Create the intersection curve.
    const float minTheta = 2.0f*Mathf::PI/3.0f;
    const float maxTheta = 4.0f*Mathf::PI/3.0f;
    float theta, cs, sn, t, tmp, discr;
    VertexBuffer* vbuffer = new0 VertexBuffer(1024, vstride);
    mCurve0 = new0 Polysegment(vformat, vbuffer, true);
    mScene->AttachChild(mCurve0);
    vba.ApplyTo(mCurve0);
    int numPoints = vba.GetNumVertices();
    float multiplier = (maxTheta - minTheta)/(float)(numPoints - 1);
    for (i = 0; i < numPoints; ++i)
    {
        theta = minTheta + multiplier*i;
        cs = Mathf::Cos(theta);
        sn = Mathf::Sin(theta);
        tmp = mC0 + mRadius1*cs;
        discr = Mathf::FAbs(mRadius0*mRadius0 - tmp*tmp);
        t = (-mRadius1*mW2*sn - Mathf::Sqrt(discr))/mW1;

        Float3& position = vba.Position<Float3>(i);
        position[0] = mC0 + mRadius1*cs;
        position[1] = +mRadius1*sn*mW2 + t*mW1;
        position[2] = -mRadius1*sn*mW1 + t*mW2;
        vba.Color<Float3>(0, i) = Float3(0.0f, 0.5f, 0.0f);
    }
    mCurve0->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());
    mVisible.Insert(mCurve0);

    vbuffer = new0 VertexBuffer(1024, vstride);
    mCurve1 = new0 Polysegment(vformat, vbuffer, true);
    mScene->AttachChild(mCurve1);
    vba.ApplyTo(mCurve1);
    numPoints = vba.GetNumVertices();
    multiplier = (maxTheta - minTheta)/(float)(numPoints - 1);
    for (i = 0; i < numPoints; ++i)
    {
        theta = minTheta + multiplier*i;
        cs = Mathf::Cos(theta);
        sn = Mathf::Sin(theta);
        tmp = mC0 + mRadius1*cs;
        discr = Mathf::FAbs(mRadius0*mRadius0 - tmp*tmp);
        t = (-mRadius1*mW2*sn + Mathf::Sqrt(discr))/mW1;

        Float3& position = vba.Position<Float3>(i);
        position[0] = mC0 + mRadius1*cs;
        position[1] = +mRadius1*sn*mW2 + t*mW1;
        position[2] = -mRadius1*sn*mW1 + t*mW2;
        vba.Color<Float3>(0, i) = Float3(0.0f, 0.5f, 0.0f);
    }
    mCurve1->SetEffectInstance(VertexColor3Effect::CreateUniqueInstance());
    mVisible.Insert(mCurve1);
}
Пример #6
0
//----------------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------------
void FreeFormDeformation::CreatePolylines ()
{
    // Generate the polylines that connect adjacent control points.
    mPolysegmentRoot = new0 Node();
    mTrnNode->AttachChild(mPolysegmentRoot);

    VertexColor3Effect* effect = new0 VertexColor3Effect();
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0);
    int vstride = vformat->GetStride();

    VertexBufferAccessor vba;
    VertexBuffer* vbuffer;
    Polysegment* segment;

    int i0, i1, i2;
    for (i0 = 0; i0 < mQuantity; ++i0)
    {
        for (i1 = 0; i1 < mQuantity; ++i1)
        {
            for (i2 = 0; i2 < mQuantity-1; ++i2)
            {
                vbuffer = new0 VertexBuffer(2, vstride);
                vba.ApplyTo(vformat, vbuffer);
                vba.Position<Vector3f>(0) =
                    mVolume->GetControlPoint(i0, i1, i2);
                vba.Position<Vector3f>(1) =
                    mVolume->GetControlPoint(i0, i1, i2+1);
                vba.Color<Float3>(0, 0) = Float3(0.0f, 0.0f, 0.75f);
                vba.Color<Float3>(0, 1) = Float3(0.0f, 0.0f, 0.75f);
                segment = new0 Polysegment(vformat, vbuffer, true);
                segment->SetEffectInstance(effect->CreateInstance());
                mPolysegmentRoot->AttachChild(segment);
            }
        }

        for (i2 = 0; i2 < mQuantity; ++i2)
        {
            for (i1 = 0; i1 < mQuantity-1; ++i1)
            {
                vbuffer = new0 VertexBuffer(2, vstride);
                vba.ApplyTo(vformat, vbuffer);
                vba.Position<Vector3f>(0) =
                    mVolume->GetControlPoint(i0, i1, i2);
                vba.Position<Vector3f>(1) =
                    mVolume->GetControlPoint(i0, i1+1, i2);
                vba.Color<Float3>(0, 0) = Float3(0.0f, 0.75f, 0.0f);
                vba.Color<Float3>(0, 1) = Float3(0.0f, 0.75f, 0.0f);
                segment = new0 Polysegment(vformat, vbuffer, true);
                segment->SetEffectInstance(effect->CreateInstance());
                mPolysegmentRoot->AttachChild(segment);
            }
        }
    }

    for (i0 = 0; i0 < mQuantity-1; ++i0)
    {
        for (i1 = 0; i1 < mQuantity; ++i1)
        {
            for (i2 = 0; i2 < mQuantity; ++i2)
            {
                vbuffer = new0 VertexBuffer(2, vstride);
                vba.ApplyTo(vformat, vbuffer);
                vba.Position<Vector3f>(0) =
                    mVolume->GetControlPoint(i0, i1, i2);
                vba.Position<Vector3f>(1) =
                    mVolume->GetControlPoint(i0+1, i1, i2);
                vba.Color<Float3>(0,0) = Float3(0.75f, 0.0f, 0.0f);
                vba.Color<Float3>(0,1) = Float3(0.75f, 0.0f, 0.0f);
                segment = new0 Polysegment(vformat, vbuffer, true);
                segment->SetEffectInstance(effect->CreateInstance());
                mPolysegmentRoot->AttachChild(segment);
            }
        }
    }
}
Пример #8
0
//----------------------------------------------------------------------------
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;
}
Пример #9
0
//----------------------------------------------------------------------------
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;
}
Пример #10
0
//----------------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------------
bool PolyhedronDistance::ApplyTransform (unsigned char key)
{
    APoint trn;
    HMatrix rot, incr;
    float trnSpeed = 0.1f;
    float rotSpeed = 0.1f;

    switch (key)
    {
        case 'x':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.X() -= trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'X':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.X() += trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'y':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.Y() -= trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'Y':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.Y() += trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'z':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.Z() -= trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'Z':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.Z() += trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 's':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.X() -= trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'S':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.X() += trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 't':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.Y() -= trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'T':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.Y() += trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'u':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.Z() -= trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'U':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.Z() += trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'a':
            rot = mTetras[0]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Y, rotSpeed);
            mTetras[0]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'A':
            rot = mTetras[0]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Y, -rotSpeed);
            mTetras[0]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'b':
            rot = mTetras[1]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Z, rotSpeed);
            mTetras[1]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'B':
            rot = mTetras[1]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Z, -rotSpeed);
            mTetras[1]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'c':
            rot = mTetras[0]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_X, 1.3f*rotSpeed);
            mTetras[0]->LocalTransform.SetRotate(incr*rot);
            rot = mTetras[1]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Z, -rotSpeed);
            mTetras[1]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'C':
            rot = mTetras[0]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_X, -1.3f*rotSpeed);
            mTetras[0]->LocalTransform.SetRotate(incr*rot);
            rot = mTetras[1]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Z, rotSpeed);
            mTetras[1]->LocalTransform.SetRotate(incr*rot);
            break;
        default:
            return false;
    }

    // Prevent solution point coordinates from being negative.  The polyhedron
    // distance calculator expects solution points to be in the first octant.
    // Vertices are offset by mOffsetMagnitude*Vector3f(1,1,1) in
    // UpdateSegments() before the call to the distance routine.  Here we make
    // sure that no translation of a polyhedron takes it so far into one of the
    // other 7 octants that the offset will not be sufficient to guarantee that
    // the solution points lie in the first octant.
    VertexBufferAccessor vba;
    float threshold = -mOffsetMagnitude + trnSpeed;
    for (int j = 0; j < 2; ++j)
    {
        const APoint& wTrn = mTetras[j]->WorldTransform.GetTranslate();
        const HMatrix& wRot = mTetras[j]->WorldTransform.GetRotate();
        vba.ApplyTo(mTetras[j]);
        for (int i = 0; i < 4; i++)
        {
            AVector relPosition = vba.Position<Float3>(i);
            APoint position = wTrn + wRot*relPosition;
            APoint trn = mTetras[j]->LocalTransform.GetTranslate();
            for (int k = 0; k < 3; ++k)
            {
                if (position[k] < threshold)
                {
                    trn[k] += trnSpeed;
                }
            }
            mTetras[j]->LocalTransform.SetTranslate(trn);
        }
    }

    mScene->Update();
    UpdateSegments();
    return true;
}
//----------------------------------------------------------------------------
void PolyhedronDistance::UpdateSegments ()
{
    // Two segments make the line easier to see.
    Vector3f U[2][4];

    // Offset the polyhedra so far into the first octant that we are unlikely
    // to translate them out of that octant during a run.
    mOffsetMagnitude = 20.0f;
    Vector3f offset = mOffsetMagnitude*Vector3f::ONE;

    VertexBufferAccessor vba;
    int i;
    for (i = 0; i < 2; ++i)
    {
        const APoint& wTrn = mTetras[i]->WorldTransform.GetTranslate();
        const HMatrix& wRot = mTetras[i]->WorldTransform.GetRotate();
        vba.ApplyTo(mTetras[i]);
        for (int j = 0; j < 4; ++j)
        {
            AVector relPosition = vba.Position<Float3>(j);
            APoint position = wTrn + wRot*relPosition;
            U[i][j] = Vector3f(position[0] + offset[0],
                position[1] + offset[1], position[2] + offset[2]);
        }
    }

    vba.ApplyTo(mSegments[0]);
    Vector3f vertex[2] =
    {
        vba.Position<Vector3f>(0),
        vba.Position<Vector3f>(1)
    };

    int statusCode;

    LCPPolyDist3(4, U[0], 4, mFaces, 4, U[1], 4, mFaces, statusCode,
        mSeparation, vertex);

    vba.Position<Vector3f>(0) = vertex[0];
    vba.Position<Vector3f>(1) = vertex[1];

    if ((statusCode != LCPPolyDist3::SC_FOUND_SOLUTION &&
        statusCode != LCPPolyDist3::SC_TEST_POINTS_TEST_FAILED &&
        statusCode != LCPPolyDist3::SC_FOUND_TRIVIAL_SOLUTION) ||
        mSeparation < 0.0f)
    {
        // Do not draw the line joining nearest points if returns from
        // LCPPolyDist are not appropriate.
        for (i = 0; i < 2; ++i)
        {
            vba.Position<Vector3f>(i) = -offset;
        }
    }

    // Correct for the offset and set up endpoints for the segment.
    for (i = 0; i < 2; ++i)
    {
        vba.Position<Vector3f>(i) -= offset;

        // The adjustment with mSmall "centers" the endpoint tetra on the
        // solution points.
        Vector3f temp = vba.Position<Vector3f>(i) -
            (mSmall/3.0f)*Vector3f::ONE;
        mTetras[i + 2]->LocalTransform.SetTranslate(temp);
    }

    // Double-up the line for better visibility.
    vertex[0] = vba.Position<Vector3f>(0);
    vertex[1] = vba.Position<Vector3f>(1);
    vba.ApplyTo(mSegments[1]);
    const float epsilon = 0.002f;
    for (i = 0; i < 2; ++i)
    {
        vba.Position<Vector3f>(i) = vertex[i] + epsilon*Vector3f::ONE;
    }

    for (i = 0; i < 2; ++i)
    {
        mSegments[i]->UpdateModelSpace(Visual::GU_MODEL_BOUND_ONLY);
        mSegments[i]->Update();
        mRenderer->Update(mSegments[i]->GetVertexBuffer());
    }

    mScene->Update();
}